From 200fc56a4ac787d74475f434ebb20558f46708c9 Mon Sep 17 00:00:00 2001
From: dignow
Date: Sun, 6 Aug 2023 14:00:48 +0800
Subject: [PATCH 01/75] tmp commit
Signed-off-by: dignow
---
flutter/lib/models/input_model.dart | 74 +++++++++++++++++-----------
libs/hbb_common/protos/message.proto | 20 ++++++++
2 files changed, 64 insertions(+), 30 deletions(-)
diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart
index 6b50aa37f..eeaa1a441 100644
--- a/flutter/lib/models/input_model.dart
+++ b/flutter/lib/models/input_model.dart
@@ -592,17 +592,52 @@ class InputModel {
return;
}
evt['type'] = type;
+
+ final pos = handlePointerDevicePos(
+ x,
+ y,
+ isMove,
+ type,
+ onExit: onExit,
+ buttons: evt['buttons'],
+ );
+ if (pos == null) {
+ return;
+ }
+ evt['x'] = '${pos.x}}';
+ evt['y'] = '${pos.y}';
+
+ Map mapButtons = {
+ kPrimaryMouseButton: 'left',
+ kSecondaryMouseButton: 'right',
+ kMiddleMouseButton: 'wheel',
+ kBackMouseButton: 'back',
+ kForwardMouseButton: 'forward'
+ };
+ evt['buttons'] = mapButtons[evt['buttons']] ?? '';
+
+ bind.sessionSendMouse(sessionId: sessionId, msg: json.encode(evt));
+ }
+
+ Point? handlePointerDevicePos(
+ double x,
+ double y,
+ bool isMove,
+ String evtType, {
+ bool onExit = false,
+ int buttons = kPrimaryMouseButton,
+ }) {
y -= CanvasModel.topToEdge;
x -= CanvasModel.leftToEdge;
final canvasModel = parent.target!.canvasModel;
- final nearThr = 3;
- var nearRight = (canvasModel.size.width - x) < nearThr;
- var nearBottom = (canvasModel.size.height - y) < nearThr;
-
final ffiModel = parent.target!.ffiModel;
if (isMove) {
canvasModel.moveDesktopMouse(x, y);
}
+
+ final nearThr = 3;
+ var nearRight = (canvasModel.size.width - x) < nearThr;
+ var nearBottom = (canvasModel.size.height - y) < nearThr;
final d = ffiModel.display;
final imageWidth = d.width * canvasModel.scale;
final imageHeight = d.height * canvasModel.scale;
@@ -650,7 +685,7 @@ class InputModel {
} catch (e) {
debugPrintStack(
label: 'canvasModel.scale value ${canvasModel.scale}, $e');
- return;
+ return null;
}
int minX = d.x.toInt();
@@ -661,38 +696,17 @@ class InputModel {
evtY = trySetNearestRange(evtY, minY, maxY, 5);
if (evtX < minX || evtY < minY || evtX > maxX || evtY > maxY) {
// If left mouse up, no early return.
- if (evt['buttons'] != kPrimaryMouseButton || type != 'up') {
- return;
+ if (buttons != kPrimaryMouseButton || evtType != 'up') {
+ return null;
}
}
- if (type != '') {
+ if (evtType != '') {
evtX = 0;
evtY = 0;
}
- evt['x'] = '$evtX';
- evt['y'] = '$evtY';
- var buttons = '';
- switch (evt['buttons']) {
- case kPrimaryMouseButton:
- buttons = 'left';
- break;
- case kSecondaryMouseButton:
- buttons = 'right';
- break;
- case kMiddleMouseButton:
- buttons = 'wheel';
- break;
- case kBackMouseButton:
- buttons = 'back';
- break;
- case kForwardMouseButton:
- buttons = 'forward';
- break;
- }
- evt['buttons'] = buttons;
- bind.sessionSendMouse(sessionId: sessionId, msg: json.encode(evt));
+ return Point(evtX, evtY);
}
/// Web only
diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto
index e6862bc80..82206cbf2 100644
--- a/libs/hbb_common/protos/message.proto
+++ b/libs/hbb_common/protos/message.proto
@@ -118,9 +118,29 @@ message TouchScaleUpdate {
int32 scale = 1;
}
+message TouchPanStart {
+ int32 x = 1;
+ int32 y = 2;
+}
+
+message TouchPanUpdate {
+ // The delta x position relative to the previous position.
+ int32 x = 1;
+ // The delta y position relative to the previous position.
+ int32 y = 2;
+}
+
+message TouchPanEnd {
+ int32 x = 1;
+ int32 y = 2;
+}
+
message TouchEvent {
oneof union {
TouchScaleUpdate scale_update = 1;
+ TouchPanStart pan_start = 2;
+ TouchPanUpdate pan_update = 3;
+ TouchPanEnd pan_end = 4;
}
}
From 8999bbf2974722ec60d9732b303f322613b4341e Mon Sep 17 00:00:00 2001
From: dignow
Date: Tue, 8 Aug 2023 23:53:53 +0800
Subject: [PATCH 02/75] tmp commit
Signed-off-by: dignow
---
flutter/lib/models/input_model.dart | 71 +++++++++++++++++------------
1 file changed, 42 insertions(+), 29 deletions(-)
diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart
index eeaa1a441..e8cd92a9c 100644
--- a/flutter/lib/models/input_model.dart
+++ b/flutter/lib/models/input_model.dart
@@ -223,14 +223,8 @@ class InputModel {
command: command);
}
- Map getEvent(PointerEvent evt, String type) {
+ Map _getMouseEvent(PointerEvent evt, String type) {
final Map out = {};
- out['x'] = evt.position.dx;
- out['y'] = evt.position.dy;
- if (alt) out['alt'] = 'true';
- if (shift) out['shift'] = 'true';
- if (ctrl) out['ctrl'] = 'true';
- if (command) out['command'] = 'true';
// Check update event type and set buttons to be sent.
int buttons = _lastButtons;
@@ -260,7 +254,6 @@ class InputModel {
out['buttons'] = buttons;
out['type'] = type;
-
return out;
}
@@ -292,7 +285,7 @@ class InputModel {
}
/// Modify the given modifier map [evt] based on current modifier key status.
- Map modify(Map evt) {
+ Map modify(Map evt) {
if (ctrl) evt['ctrl'] = 'true';
if (shift) evt['shift'] = 'true';
if (alt) evt['alt'] = 'true';
@@ -334,13 +327,14 @@ class InputModel {
isPhysicalMouse.value = true;
}
if (isPhysicalMouse.value) {
- handleMouse(getEvent(e, _kMouseEventMove));
+ handleMouse(_getMouseEvent(e, _kMouseEventMove), e.position);
}
}
void onPointerPanZoomStart(PointerPanZoomStartEvent e) {
_lastScale = 1.0;
_stopFling = true;
+ handlePointerEvent('touch', 'pan_start', e);
}
// https://docs.flutter.dev/release/breaking-changes/trackpad-gestures
@@ -465,21 +459,21 @@ class InputModel {
}
}
if (isPhysicalMouse.value) {
- handleMouse(getEvent(e, _kMouseEventDown));
+ handleMouse(_getMouseEvent(e, _kMouseEventDown), e.position);
}
}
void onPointUpImage(PointerUpEvent e) {
if (e.kind != ui.PointerDeviceKind.mouse) return;
if (isPhysicalMouse.value) {
- handleMouse(getEvent(e, _kMouseEventUp));
+ handleMouse(_getMouseEvent(e, _kMouseEventUp), e.position);
}
}
void onPointMoveImage(PointerMoveEvent e) {
if (e.kind != ui.PointerDeviceKind.mouse) return;
if (isPhysicalMouse.value) {
- handleMouse(getEvent(e, _kMouseEventMove));
+ handleMouse(_getMouseEvent(e, _kMouseEventMove), e.position);
}
}
@@ -504,19 +498,16 @@ class InputModel {
}
void refreshMousePos() => handleMouse({
- 'x': lastMousePos.dx,
- 'y': lastMousePos.dy,
'buttons': 0,
'type': _kMouseEventMove,
- });
+ }, lastMousePos);
void tryMoveEdgeOnExit(Offset pos) => handleMouse(
{
- 'x': pos.dx,
- 'y': pos.dy,
'buttons': 0,
'type': _kMouseEventMove,
},
+ pos,
onExit: true,
);
@@ -550,17 +541,27 @@ class InputModel {
return Offset(x, y);
}
- void handleMouse(
- Map evt, {
- bool onExit = false,
- }) {
- double x = evt['x'];
- double y = max(0.0, evt['y']);
- final cursorModel = parent.target!.cursorModel;
+ void handlePointerEvent(String kind, String type, PointerEvent e) {
+ if (checkPeerControlProtected(e.position.dx, max(0.0, e.position.dy))) {
+ return;
+ }
+ // Only touch events are handled for now. So we can just ignore buttons.
+ // to-do: handle mouse events
+ bind.sessionSendPointer(
+ sessionId: sessionId,
+ msg: json.encode({
+ modify({
+ kind: {type: e.position.toString()}
+ })
+ }),
+ );
+ }
+ bool checkPeerControlProtected(double x, double y) {
+ final cursorModel = parent.target!.cursorModel;
if (cursorModel.isPeerControlProtected) {
lastMousePos = ui.Offset(x, y);
- return;
+ return true;
}
if (!cursorModel.gotMouseControl) {
@@ -571,10 +572,23 @@ class InputModel {
cursorModel.gotMouseControl = true;
} else {
lastMousePos = ui.Offset(x, y);
- return;
+ return true;
}
}
lastMousePos = ui.Offset(x, y);
+ return false;
+ }
+
+ void handleMouse(
+ Map evt,
+ Offset offset, {
+ bool onExit = false,
+ }) {
+ double x = offset.dx;
+ double y = max(0.0, offset.dy);
+ if (checkPeerControlProtected(x, y)) {
+ return;
+ }
var type = '';
var isMove = false;
@@ -615,8 +629,7 @@ class InputModel {
kForwardMouseButton: 'forward'
};
evt['buttons'] = mapButtons[evt['buttons']] ?? '';
-
- bind.sessionSendMouse(sessionId: sessionId, msg: json.encode(evt));
+ bind.sessionSendMouse(sessionId: sessionId, msg: json.encode(modify(evt)));
}
Point? handlePointerDevicePos(
From 933c99110ccc3e607e70f2ba97211266b5fcf5eb Mon Sep 17 00:00:00 2001
From: dignow
Date: Wed, 9 Aug 2023 07:39:16 +0800
Subject: [PATCH 03/75] tmp commit
Signed-off-by: dignow
---
flutter/lib/models/input_model.dart | 85 ++++++++++++++++++++---------
1 file changed, 58 insertions(+), 27 deletions(-)
diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart
index e8cd92a9c..ef1a90d6e 100644
--- a/flutter/lib/models/input_model.dart
+++ b/flutter/lib/models/input_model.dart
@@ -62,11 +62,11 @@ class InputModel {
int _lastButtons = 0;
Offset lastMousePos = Offset.zero;
- get id => parent.target?.id ?? "";
-
late final SessionID sessionId;
bool get keyboardPerm => parent.target!.ffiModel.keyboard;
+ String get id => parent.target?.id ?? '';
+ String? get peerPlatform => parent.target?.ffiModel.pi.platform;
InputModel(this.parent) {
sessionId = parent.target!.sessionId;
@@ -334,21 +334,26 @@ class InputModel {
void onPointerPanZoomStart(PointerPanZoomStartEvent e) {
_lastScale = 1.0;
_stopFling = true;
- handlePointerEvent('touch', 'pan_start', e);
+
+ if (peerPlatform == kPeerPlatformAndroid) {
+ handlePointerEvent('touch', 'pan_start', e.position);
+ }
}
// https://docs.flutter.dev/release/breaking-changes/trackpad-gestures
void onPointerPanZoomUpdate(PointerPanZoomUpdateEvent e) {
- final scale = ((e.scale - _lastScale) * 1000).toInt();
- _lastScale = e.scale;
+ if (peerPlatform != kPeerPlatformAndroid) {
+ final scale = ((e.scale - _lastScale) * 1000).toInt();
+ _lastScale = e.scale;
- if (scale != 0) {
- bind.sessionSendPointer(
- sessionId: sessionId,
- msg: json.encode({
- 'touch': {'scale': scale}
- }));
- return;
+ if (scale != 0) {
+ bind.sessionSendPointer(
+ sessionId: sessionId,
+ msg: json.encode({
+ 'touch': {'scale': scale}
+ }));
+ return;
+ }
}
final delta = e.panDelta;
@@ -356,7 +361,8 @@ class InputModel {
var x = delta.dx.toInt();
var y = delta.dy.toInt();
- if (parent.target?.ffiModel.pi.platform == kPeerPlatformLinux) {
+ if (peerPlatform == kPeerPlatformLinux ||
+ peerPlatform == kPeerPlatformAndroid) {
_trackpadScrollUnsent += (delta * _trackpadSpeed);
x = _trackpadScrollUnsent.dx.truncate();
y = _trackpadScrollUnsent.dy.truncate();
@@ -372,9 +378,13 @@ class InputModel {
}
}
if (x != 0 || y != 0) {
- bind.sessionSendMouse(
- sessionId: sessionId,
- msg: '{"type": "trackpad", "x": "$x", "y": "$y"}');
+ if (peerPlatform == kPeerPlatformAndroid) {
+ handlePointerEvent('touch', 'pan_move', e.delta);
+ } else {
+ bind.sessionSendMouse(
+ sessionId: sessionId,
+ msg: '{"type": "trackpad", "x": "$x", "y": "$y"}');
+ }
}
}
@@ -430,6 +440,11 @@ class InputModel {
}
void onPointerPanZoomEnd(PointerPanZoomEndEvent e) {
+ if (peerPlatform == kPeerPlatformAndroid) {
+ handlePointerEvent('touch', 'pan_end', e.position);
+ return;
+ }
+
bind.sessionSendPointer(
sessionId: sessionId,
msg: json.encode({
@@ -541,23 +556,39 @@ class InputModel {
return Offset(x, y);
}
- void handlePointerEvent(String kind, String type, PointerEvent e) {
- if (checkPeerControlProtected(e.position.dx, max(0.0, e.position.dy))) {
+ void handlePointerEvent(String kind, String type, Offset offset) {
+ double x = offset.dx;
+ double y = max(0.0, offset.dy);
+ if (_checkPeerControlProtected(x, y)) {
return;
}
// Only touch events are handled for now. So we can just ignore buttons.
// to-do: handle mouse events
- bind.sessionSendPointer(
- sessionId: sessionId,
- msg: json.encode({
- modify({
- kind: {type: e.position.toString()}
- })
- }),
+
+ final isMoveTypes = ['pan', 'pan_start', 'pan_end'];
+ final pos = handlePointerDevicePos(
+ x,
+ y,
+ isMoveTypes.contains(type),
+ type,
);
+ if (pos == null) {
+ return;
+ }
+
+ final evt = {
+ kind: {
+ type: {
+ 'x': '${pos.x}',
+ 'y': '${pos.y}',
+ }
+ }
+ };
+ bind.sessionSendPointer(
+ sessionId: sessionId, msg: json.encode({modify(evt)}));
}
- bool checkPeerControlProtected(double x, double y) {
+ bool _checkPeerControlProtected(double x, double y) {
final cursorModel = parent.target!.cursorModel;
if (cursorModel.isPeerControlProtected) {
lastMousePos = ui.Offset(x, y);
@@ -586,7 +617,7 @@ class InputModel {
}) {
double x = offset.dx;
double y = max(0.0, offset.dy);
- if (checkPeerControlProtected(x, y)) {
+ if (_checkPeerControlProtected(x, y)) {
return;
}
From d6f1abad959e21e4dbdc4cb05c1a976083b8bb2c Mon Sep 17 00:00:00 2001
From: dignow
Date: Wed, 9 Aug 2023 09:00:23 +0800
Subject: [PATCH 04/75] tmp commit
Signed-off-by: dignow
---
.../com/carriez/flutter_hbb/InputService.kt | 31 ++++++++++++++
.../com/carriez/flutter_hbb/MainService.kt | 17 ++++++--
libs/scrap/src/android/ffi.rs | 6 +--
src/server/connection.rs | 42 +++++++++++++++++--
4 files changed, 85 insertions(+), 11 deletions(-)
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
index 905a2734d..8e14a590d 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
@@ -26,6 +26,13 @@ const val WHEEL_BUTTON_UP = 34
const val WHEEL_DOWN = 523331
const val WHEEL_UP = 963
+const val TOUCH_SCALE_START = 1
+const val TOUCH_SCALE = 2
+const val TOUCH_SCALE_END = 3
+const val TOUCH_PAN_START = 4
+const val TOUCH_PAN_UPDATE = 5
+const val TOUCH_PAN_END = 6
+
const val WHEEL_STEP = 120
const val WHEEL_DURATION = 50L
const val LONG_TAP_DELAY = 200L
@@ -167,6 +174,30 @@ class InputService : AccessibilityService() {
}
}
+ @RequiresApi(Build.VERSION_CODES.N)
+ fun onTouchInput(mask: Int, _x: Int, _y: Int) {
+ val x = max(0, _x)
+ val y = max(0, _y)
+ when (mask) {
+ TOUCH_PAN_UPDATE -> {
+ mouseX += x * SCREEN_INFO.scale
+ mouseY += y * SCREEN_INFO.scale
+ continueGesture(mouseX, mouseY)
+ }
+ TOUCH_PAN_START -> {
+ mouseX = x * SCREEN_INFO.scale
+ mouseY = y * SCREEN_INFO.scale
+ startGesture(mouseX, mouseY)
+ }
+ TOUCH_PAN_END -> {
+ mouseX = x * SCREEN_INFO.scale
+ mouseY = y * SCREEN_INFO.scale
+ endGesture(mouseX, mouseY)
+ }
+ else -> {}
+ }
+ }
+
@RequiresApi(Build.VERSION_CODES.N)
private fun consumeWheelActions() {
if (isWheelActionsPolling) {
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt
index 78e4e451e..f32203703 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt
@@ -71,17 +71,26 @@ class MainService : Service() {
@Keep
@RequiresApi(Build.VERSION_CODES.N)
- fun rustMouseInput(mask: Int, x: Int, y: Int) {
+ fun rustPointerInput(kind: String, mask: Int, x: Int, y: Int) {
// turn on screen with LIFT_DOWN when screen off
- if (!powerManager.isInteractive && mask == LIFT_DOWN) {
+ if (!powerManager.isInteractive && (kind == "touch" || mask == LIFT_DOWN)) {
if (wakeLock.isHeld) {
- Log.d(logTag,"Turn on Screen, WakeLock release")
+ Log.d(logTag, "Turn on Screen, WakeLock release")
wakeLock.release()
}
Log.d(logTag,"Turn on Screen")
wakeLock.acquire(5000)
} else {
- InputService.ctx?.onMouseInput(mask,x,y)
+ when (name) {
+ "touch" -> {
+ InputService.ctx?.onTouchInput(mask, x, y)
+ }
+ "mouse" -> {
+ InputService.ctx?.onMouseInput(mask, x, y)
+ }
+ else -> {
+ }
+ }
}
}
diff --git a/libs/scrap/src/android/ffi.rs b/libs/scrap/src/android/ffi.rs
index 6855fd3f6..3801bbc87 100644
--- a/libs/scrap/src/android/ffi.rs
+++ b/libs/scrap/src/android/ffi.rs
@@ -154,7 +154,7 @@ pub extern "system" fn Java_com_carriez_flutter_1hbb_MainService_init(
}
}
-pub fn call_main_service_mouse_input(mask: i32, x: i32, y: i32) -> JniResult<()> {
+pub fn call_main_service_pointer_input(kind: String, mask: i32, x: i32, y: i32) -> JniResult<()> {
if let (Some(jvm), Some(ctx)) = (
JVM.read().unwrap().as_ref(),
MAIN_SERVICE_CTX.read().unwrap().as_ref(),
@@ -162,9 +162,9 @@ pub fn call_main_service_mouse_input(mask: i32, x: i32, y: i32) -> JniResult<()>
let mut env = jvm.attach_current_thread_as_daemon()?;
env.call_method(
ctx,
- "rustMouseInput",
+ "rustPointerInput",
"(III)V",
- &[JValue::Int(mask), JValue::Int(x), JValue::Int(y)],
+ &[JValue(kind), JValue::Int(mask), JValue::Int(x), JValue::Int(y)],
)?;
return Ok(());
} else {
diff --git a/src/server/connection.rs b/src/server/connection.rs
index e32a4c1c3..913c831da 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -1546,8 +1546,10 @@ impl Connection {
match msg.union {
Some(message::Union::MouseEvent(me)) => {
#[cfg(any(target_os = "android", target_os = "ios"))]
- if let Err(e) = call_main_service_mouse_input(me.mask, me.x, me.y) {
- log::debug!("call_main_service_mouse_input fail:{}", e);
+ if let Err(e) =
+ call_main_service_pointer_input("mouse".to_string(), me.mask, me.x, me.y)
+ {
+ log::debug!("call_main_service_pointer_input fail:{}", e);
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
if self.peer_keyboard_enabled() {
@@ -1559,8 +1561,40 @@ impl Connection {
self.input_mouse(me, self.inner.id());
}
}
- Some(message::Union::PointerDeviceEvent(pde)) =>
- {
+ Some(message::Union::PointerDeviceEvent(pde)) => {
+ #[cfg(any(target_os = "android", target_os = "ios"))]
+ if let Err(e) = match pde.union {
+ Some(pointer_device_event::Union::TouchEvent(touch)) => match touch.union {
+ Some(touch_event::Union::PanStart(pan_start)) => {
+ call_main_service_pointer_input(
+ "touch".to_string(),
+ 4,
+ pan_start.x,
+ pan_start.y,
+ )
+ }
+ Some(touch_event::Union::PanUpdate(pan_start)) => {
+ call_main_service_pointer_input(
+ "touch".to_string(),
+ 5,
+ pan_start.x,
+ pan_start.y,
+ )
+ }
+ Some(touch_event::Union::PanEnd(pan_start)) => {
+ call_main_service_pointer_input(
+ "touch".to_string(),
+ 6,
+ pan_start.x,
+ pan_start.y,
+ )
+ }
+ _ => Ok(()),
+ },
+ _ => Ok(()),
+ } {
+ log::debug!("call_main_service_pointer_input fail:{}", e);
+ }
#[cfg(not(any(target_os = "android", target_os = "ios")))]
if self.peer_keyboard_enabled() {
MOUSE_MOVE_TIME.store(get_time(), Ordering::SeqCst);
From 06ee68f836a4e5635ec41fc460afe39d5e851f41 Mon Sep 17 00:00:00 2001
From: dignow
Date: Wed, 9 Aug 2023 22:26:13 +0800
Subject: [PATCH 05/75] tmp commit
Signed-off-by: dignow
---
flutter/lib/models/input_model.dart | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart
index ef1a90d6e..18e9d0d2f 100644
--- a/flutter/lib/models/input_model.dart
+++ b/flutter/lib/models/input_model.dart
@@ -649,7 +649,7 @@ class InputModel {
if (pos == null) {
return;
}
- evt['x'] = '${pos.x}}';
+ evt['x'] = '${pos.x}';
evt['y'] = '${pos.y}';
Map mapButtons = {
From 93a600a0a8d86cfdb632f15552cb0b887448e0fc Mon Sep 17 00:00:00 2001
From: dignow
Date: Wed, 9 Aug 2023 23:42:53 +0800
Subject: [PATCH 06/75] tmp commit
Signed-off-by: dignow
---
flutter/lib/common/widgets/remote_input.dart | 12 +--
flutter/lib/consts.dart | 3 +
flutter/lib/models/input_model.dart | 101 ++++++++++++-------
src/flutter_ffi.rs | 41 ++++++--
src/server/connection.rs | 12 +--
src/ui_session_interface.rs | 43 ++++++++
6 files changed, 155 insertions(+), 57 deletions(-)
diff --git a/flutter/lib/common/widgets/remote_input.dart b/flutter/lib/common/widgets/remote_input.dart
index 35eaf8a7c..b00cd1fb4 100644
--- a/flutter/lib/common/widgets/remote_input.dart
+++ b/flutter/lib/common/widgets/remote_input.dart
@@ -6,6 +6,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import 'package:flutter_hbb/common.dart';
+import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/models/model.dart';
import 'package:flutter_hbb/models/input_model.dart';
@@ -263,9 +264,9 @@ class _RawTouchGestureDetectorRegionState
if (scale != 0) {
bind.sessionSendPointer(
sessionId: sessionId,
- msg: json.encode({
- 'touch': {'scale': scale}
- }));
+ msg: json.encode(
+ PointerEventToRust(kPointerEventKindTouch, 'scale', scale)
+ .toJson()));
}
} else {
// mobile
@@ -283,9 +284,8 @@ class _RawTouchGestureDetectorRegionState
if (isDesktop) {
bind.sessionSendPointer(
sessionId: sessionId,
- msg: json.encode({
- 'touch': {'scale': 0}
- }));
+ msg: json.encode(
+ PointerEventToRust(kPointerEventKindTouch, 'scale', 0).toJson()));
} else {
// mobile
_scale = 1;
diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart
index 5376196e4..f26e83e01 100644
--- a/flutter/lib/consts.dart
+++ b/flutter/lib/consts.dart
@@ -54,6 +54,9 @@ const String kTabLabelSettingPage = "Settings";
const String kWindowPrefix = "wm_";
const int kWindowMainId = 0;
+const String kPointerEventKindTouch = "touch";
+const String kPointerEventKindMouse = "mouse";
+
// the executable name of the portable version
const String kEnvPortableExecutable = "RUSTDESK_APPNAME";
diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart
index 18e9d0d2f..9b1ec4437 100644
--- a/flutter/lib/models/input_model.dart
+++ b/flutter/lib/models/input_model.dart
@@ -35,6 +35,24 @@ extension ToString on MouseButtons {
}
}
+class PointerEventToRust {
+ final String kind;
+ final String type;
+ final dynamic value;
+
+ PointerEventToRust(this.kind, this.type, this.value);
+
+ Map toJson() {
+ return {
+ 'k': kind,
+ 'v': {
+ 't': type,
+ 'v': value,
+ }
+ };
+ }
+}
+
class InputModel {
final WeakReference parent;
String keyboardMode = "legacy";
@@ -349,9 +367,9 @@ class InputModel {
if (scale != 0) {
bind.sessionSendPointer(
sessionId: sessionId,
- msg: json.encode({
- 'touch': {'scale': scale}
- }));
+ msg: json.encode(
+ PointerEventToRust(kPointerEventKindTouch, 'scale', scale)
+ .toJson()));
return;
}
}
@@ -379,7 +397,7 @@ class InputModel {
}
if (x != 0 || y != 0) {
if (peerPlatform == kPeerPlatformAndroid) {
- handlePointerEvent('touch', 'pan_move', e.delta);
+ handlePointerEvent('touch', 'pan_update', Offset(x.toDouble(), y.toDouble()));
} else {
bind.sessionSendMouse(
sessionId: sessionId,
@@ -447,9 +465,8 @@ class InputModel {
bind.sessionSendPointer(
sessionId: sessionId,
- msg: json.encode({
- 'touch': {'scale': 0}
- }));
+ msg: json.encode(
+ PointerEventToRust(kPointerEventKindTouch, 'scale', 0).toJson()));
waitLastFlingDone();
_stopFling = false;
@@ -558,34 +575,40 @@ class InputModel {
void handlePointerEvent(String kind, String type, Offset offset) {
double x = offset.dx;
- double y = max(0.0, offset.dy);
+ double y = offset.dy;
if (_checkPeerControlProtected(x, y)) {
return;
}
// Only touch events are handled for now. So we can just ignore buttons.
// to-do: handle mouse events
- final isMoveTypes = ['pan', 'pan_start', 'pan_end'];
- final pos = handlePointerDevicePos(
- x,
- y,
- isMoveTypes.contains(type),
- type,
- );
- if (pos == null) {
- return;
+ late final dynamic evtValue;
+ if (type == 'pan_update') {
+ evtValue = {
+ 'x': '${x.toInt()}',
+ 'y': '${y.toInt()}',
+ };
+ } else {
+ final isMoveTypes = ['pan_start', 'pan_end'];
+ final pos = handlePointerDevicePos(
+ kPointerEventKindTouch,
+ x,
+ y,
+ isMoveTypes.contains(type),
+ type,
+ );
+ if (pos == null) {
+ return;
+ }
+ evtValue = {
+ 'x': '${pos.x}',
+ 'y': '${pos.y}',
+ };
}
- final evt = {
- kind: {
- type: {
- 'x': '${pos.x}',
- 'y': '${pos.y}',
- }
- }
- };
+ final evt = PointerEventToRust(kind, type, evtValue).toJson();
bind.sessionSendPointer(
- sessionId: sessionId, msg: json.encode({modify(evt)}));
+ sessionId: sessionId, msg: json.encode(modify(evt)));
}
bool _checkPeerControlProtected(double x, double y) {
@@ -639,6 +662,7 @@ class InputModel {
evt['type'] = type;
final pos = handlePointerDevicePos(
+ kPointerEventKindMouse,
x,
y,
isMove,
@@ -649,8 +673,13 @@ class InputModel {
if (pos == null) {
return;
}
- evt['x'] = '${pos.x}';
- evt['y'] = '${pos.y}';
+ if (type != '') {
+ evt['x'] = 0;
+ evt['y'] = 0;
+ } else {
+ evt['x'] = '${pos.x}';
+ evt['y'] = '${pos.y}';
+ }
Map mapButtons = {
kPrimaryMouseButton: 'left',
@@ -664,6 +693,7 @@ class InputModel {
}
Point? handlePointerDevicePos(
+ String kind,
double x,
double y,
bool isMove,
@@ -738,18 +768,15 @@ class InputModel {
int maxY = (d.y + d.height).toInt() - 1;
evtX = trySetNearestRange(evtX, minX, maxX, 5);
evtY = trySetNearestRange(evtY, minY, maxY, 5);
- if (evtX < minX || evtY < minY || evtX > maxX || evtY > maxY) {
- // If left mouse up, no early return.
- if (buttons != kPrimaryMouseButton || evtType != 'up') {
- return null;
+ if (kind == kPointerEventKindMouse) {
+ if (evtX < minX || evtY < minY || evtX > maxX || evtY > maxY) {
+ // If left mouse up, no early return.
+ if (!(buttons == kPrimaryMouseButton && evtType == 'up')) {
+ return null;
+ }
}
}
- if (evtType != '') {
- evtX = 0;
- evtY = 0;
- }
-
return Point(evtX, evtY);
}
diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs
index ef4c9e2ba..cf5d23397 100644
--- a/src/flutter_ffi.rs
+++ b/src/flutter_ffi.rs
@@ -1177,14 +1177,39 @@ pub fn session_send_pointer(session_id: SessionID, msg: String) {
let ctrl = m.get("ctrl").is_some();
let shift = m.get("shift").is_some();
let command = m.get("command").is_some();
- if let Some(touch_event) = m.get("touch") {
- if let Some(scale) = touch_event.get("scale") {
- if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
- if let Some(scale) = scale.as_i64() {
- session.send_touch_scale(scale as _, alt, ctrl, shift, command);
- }
- }
- }
+ match (m.get("k"), m.get("v")) {
+ (Some(k), Some(v)) => match k.as_str() {
+ Some("touch") => match v.as_str() {
+ Some("scale") => match v.get("v") {
+ Some(scale) => {
+ if let Some(scale) = scale.as_i64() {
+ if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
+ session.send_touch_scale(scale as _, alt, ctrl, shift, command);
+ }
+ }
+ }
+ None => {}
+ },
+ Some(pan_event) => match (v.get("x"), v.get("y")) {
+ (Some(x), Some(y)) => {
+ if let Some(x) = x.as_i64() {
+ if let Some(y) = y.as_i64() {
+ if let Some(session) = SESSIONS.read().unwrap().get(&session_id)
+ {
+ session.send_touch_pan_event(
+ pan_event, x as _, y as _, alt, ctrl, shift, command,
+ );
+ }
+ }
+ }
+ }
+ _ => {}
+ },
+ _ => {}
+ },
+ _ => {}
+ },
+ _ => {}
}
}
}
diff --git a/src/server/connection.rs b/src/server/connection.rs
index 913c831da..972750fc2 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -1573,20 +1573,20 @@ impl Connection {
pan_start.y,
)
}
- Some(touch_event::Union::PanUpdate(pan_start)) => {
+ Some(touch_event::Union::PanUpdate(pan_update)) => {
call_main_service_pointer_input(
"touch".to_string(),
5,
- pan_start.x,
- pan_start.y,
+ pan_update.x,
+ pan_update.y,
)
}
- Some(touch_event::Union::PanEnd(pan_start)) => {
+ Some(touch_event::Union::PanEnd(pan_end)) => {
call_main_service_pointer_input(
"touch".to_string(),
6,
- pan_start.x,
- pan_start.y,
+ pan_end.x,
+ pan_end.y,
)
}
_ => Ok(()),
diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs
index 7ffcaac6d..23035a550 100644
--- a/src/ui_session_interface.rs
+++ b/src/ui_session_interface.rs
@@ -724,6 +724,49 @@ impl Session {
send_pointer_device_event(evt, alt, ctrl, shift, command, self);
}
+ pub fn send_touch_pan_event(
+ &self,
+ event: &str,
+ x: i32,
+ y: i32,
+ alt: bool,
+ ctrl: bool,
+ shift: bool,
+ command: bool,
+ ) {
+ let mut touch_evt = TouchEvent::new();
+ match event {
+ "pan_start" => {
+ touch_evt.set_pan_start(TouchPanStart {
+ x,
+ y,
+ ..Default::default()
+ });
+ }
+ "pan_update" => {
+ touch_evt.set_pan_update(TouchPanUpdate {
+ x,
+ y,
+ ..Default::default()
+ });
+ }
+ "pan_end" => {
+ touch_evt.set_pan_end(TouchPanEnd {
+ x,
+ y,
+ ..Default::default()
+ });
+ }
+ _ => {
+ log::warn!("unknown touch pan event: {}", event);
+ return;
+ }
+ };
+ let mut evt = PointerDeviceEvent::new();
+ evt.set_touch_event(touch_evt);
+ send_pointer_device_event(evt, alt, ctrl, shift, command, self);
+ }
+
pub fn send_mouse(
&self,
mask: i32,
From 9e0feb0b64c14c97eccea3905923dbcc7acbaab5 Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 01:02:27 +0800
Subject: [PATCH 07/75] tmp debug
Signed-off-by: dignow
---
flutter/lib/models/input_model.dart | 8 +++----
src/flutter_ffi.rs | 33 ++++++++++++++---------------
2 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart
index 9b1ec4437..5f851c54d 100644
--- a/flutter/lib/models/input_model.dart
+++ b/flutter/lib/models/input_model.dart
@@ -585,8 +585,8 @@ class InputModel {
late final dynamic evtValue;
if (type == 'pan_update') {
evtValue = {
- 'x': '${x.toInt()}',
- 'y': '${y.toInt()}',
+ 'x': x.toInt(),
+ 'y': y.toInt(),
};
} else {
final isMoveTypes = ['pan_start', 'pan_end'];
@@ -601,8 +601,8 @@ class InputModel {
return;
}
evtValue = {
- 'x': '${pos.x}',
- 'y': '${pos.y}',
+ 'x': pos.x,
+ 'y': pos.y,
};
}
diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs
index cf5d23397..c6f8ca774 100644
--- a/src/flutter_ffi.rs
+++ b/src/flutter_ffi.rs
@@ -1179,30 +1179,29 @@ pub fn session_send_pointer(session_id: SessionID, msg: String) {
let command = m.get("command").is_some();
match (m.get("k"), m.get("v")) {
(Some(k), Some(v)) => match k.as_str() {
- Some("touch") => match v.as_str() {
- Some("scale") => match v.get("v") {
+ Some("touch") => match v.get("t").and_then(|t| t.as_str()) {
+ Some("scale") => match v.get("v").and_then(|s| s.as_i64()) {
Some(scale) => {
- if let Some(scale) = scale.as_i64() {
- if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
- session.send_touch_scale(scale as _, alt, ctrl, shift, command);
- }
+ if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
+ session.send_touch_scale(scale as _, alt, ctrl, shift, command);
}
}
None => {}
},
- Some(pan_event) => match (v.get("x"), v.get("y")) {
- (Some(x), Some(y)) => {
- if let Some(x) = x.as_i64() {
- if let Some(y) = y.as_i64() {
- if let Some(session) = SESSIONS.read().unwrap().get(&session_id)
- {
- session.send_touch_pan_event(
- pan_event, x as _, y as _, alt, ctrl, shift, command,
- );
- }
+ Some(pan_event) => match v.get("v") {
+ Some(v) => match (
+ v.get("x").and_then(|x| x.as_i64()),
+ v.get("y").and_then(|y| y.as_i64()),
+ ) {
+ (Some(x), Some(y)) => {
+ if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
+ session.send_touch_pan_event(
+ pan_event, x as _, y as _, alt, ctrl, shift, command,
+ );
}
}
- }
+ _ => {}
+ },
_ => {}
},
_ => {}
From da16a799fa6851289bc18b081cfa4e715e6163f3 Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 01:10:59 +0800
Subject: [PATCH 08/75] fix build
Signed-off-by: dignow
---
libs/scrap/src/android/ffi.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/scrap/src/android/ffi.rs b/libs/scrap/src/android/ffi.rs
index 3801bbc87..78908a2ba 100644
--- a/libs/scrap/src/android/ffi.rs
+++ b/libs/scrap/src/android/ffi.rs
@@ -164,7 +164,7 @@ pub fn call_main_service_pointer_input(kind: String, mask: i32, x: i32, y: i32)
ctx,
"rustPointerInput",
"(III)V",
- &[JValue(kind), JValue::Int(mask), JValue::Int(x), JValue::Int(y)],
+ &[JValue::String(kind), JValue::Int(mask), JValue::Int(x), JValue::Int(y)],
)?;
return Ok(());
} else {
From 9476d7fdbb7edb3b3ebcaa8326622918b71af227 Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 01:24:39 +0800
Subject: [PATCH 09/75] try fix build
Signed-off-by: dignow
---
libs/scrap/src/android/ffi.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libs/scrap/src/android/ffi.rs b/libs/scrap/src/android/ffi.rs
index 78908a2ba..ba775dfd3 100644
--- a/libs/scrap/src/android/ffi.rs
+++ b/libs/scrap/src/android/ffi.rs
@@ -163,8 +163,8 @@ pub fn call_main_service_pointer_input(kind: String, mask: i32, x: i32, y: i32)
env.call_method(
ctx,
"rustPointerInput",
- "(III)V",
- &[JValue::String(kind), JValue::Int(mask), JValue::Int(x), JValue::Int(y)],
+ "(Ljava/lang/String;III)V",
+ &[JValue::Object(&JObject::from(name)), JValue::Int(mask), JValue::Int(x), JValue::Int(y)],
)?;
return Ok(());
} else {
From e89ae475f6a4d03ca79d0382e71d1fb9ea816b40 Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 03:01:46 +0800
Subject: [PATCH 10/75] fix build
Signed-off-by: dignow
---
.../main/kotlin/com/carriez/flutter_hbb/MainService.kt | 2 +-
libs/scrap/src/android/ffi.rs | 5 +++--
src/server/connection.rs | 10 +++++-----
3 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt
index f32203703..535a3f8c3 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt
@@ -81,7 +81,7 @@ class MainService : Service() {
Log.d(logTag,"Turn on Screen")
wakeLock.acquire(5000)
} else {
- when (name) {
+ when (kind) {
"touch" -> {
InputService.ctx?.onTouchInput(mask, x, y)
}
diff --git a/libs/scrap/src/android/ffi.rs b/libs/scrap/src/android/ffi.rs
index ba775dfd3..e9c60ef93 100644
--- a/libs/scrap/src/android/ffi.rs
+++ b/libs/scrap/src/android/ffi.rs
@@ -154,17 +154,18 @@ pub extern "system" fn Java_com_carriez_flutter_1hbb_MainService_init(
}
}
-pub fn call_main_service_pointer_input(kind: String, mask: i32, x: i32, y: i32) -> JniResult<()> {
+pub fn call_main_service_pointer_input(kind: &str, mask: i32, x: i32, y: i32) -> JniResult<()> {
if let (Some(jvm), Some(ctx)) = (
JVM.read().unwrap().as_ref(),
MAIN_SERVICE_CTX.read().unwrap().as_ref(),
) {
let mut env = jvm.attach_current_thread_as_daemon()?;
+ let kind = env.new_string(kind)?;
env.call_method(
ctx,
"rustPointerInput",
"(Ljava/lang/String;III)V",
- &[JValue::Object(&JObject::from(name)), JValue::Int(mask), JValue::Int(x), JValue::Int(y)],
+ &[JValue::Object(&JObject::from(kind)), JValue::Int(mask), JValue::Int(x), JValue::Int(y)],
)?;
return Ok(());
} else {
diff --git a/src/server/connection.rs b/src/server/connection.rs
index 972750fc2..f107d15a6 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -39,7 +39,7 @@ use hbb_common::{
tokio_util::codec::{BytesCodec, Framed},
};
#[cfg(any(target_os = "android", target_os = "ios"))]
-use scrap::android::call_main_service_mouse_input;
+use scrap::android::call_main_service_pointer_input;
use serde_json::{json, value::Value};
use sha2::{Digest, Sha256};
#[cfg(not(any(target_os = "android", target_os = "ios")))]
@@ -1547,7 +1547,7 @@ impl Connection {
Some(message::Union::MouseEvent(me)) => {
#[cfg(any(target_os = "android", target_os = "ios"))]
if let Err(e) =
- call_main_service_pointer_input("mouse".to_string(), me.mask, me.x, me.y)
+ call_main_service_pointer_input("mouse", me.mask, me.x, me.y)
{
log::debug!("call_main_service_pointer_input fail:{}", e);
}
@@ -1567,7 +1567,7 @@ impl Connection {
Some(pointer_device_event::Union::TouchEvent(touch)) => match touch.union {
Some(touch_event::Union::PanStart(pan_start)) => {
call_main_service_pointer_input(
- "touch".to_string(),
+ "touch",
4,
pan_start.x,
pan_start.y,
@@ -1575,7 +1575,7 @@ impl Connection {
}
Some(touch_event::Union::PanUpdate(pan_update)) => {
call_main_service_pointer_input(
- "touch".to_string(),
+ "touch",
5,
pan_update.x,
pan_update.y,
@@ -1583,7 +1583,7 @@ impl Connection {
}
Some(touch_event::Union::PanEnd(pan_end)) => {
call_main_service_pointer_input(
- "touch".to_string(),
+ "touch",
6,
pan_end.x,
pan_end.y,
From b9c8df70196ca0eeb9f8115729a3775b1cd38600 Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 03:55:03 +0800
Subject: [PATCH 11/75] debug
Signed-off-by: dignow
---
flutter/lib/models/input_model.dart | 7 +++++--
src/server/connection.rs | 11 ++---------
2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart
index 5f851c54d..eaff4ed6a 100644
--- a/flutter/lib/models/input_model.dart
+++ b/flutter/lib/models/input_model.dart
@@ -638,6 +638,7 @@ class InputModel {
Offset offset, {
bool onExit = false,
}) {
+ debugPrint('REMOVE ME ========================= 111');
double x = offset.dx;
double y = max(0.0, offset.dy);
if (_checkPeerControlProtected(x, y)) {
@@ -671,11 +672,12 @@ class InputModel {
buttons: evt['buttons'],
);
if (pos == null) {
+ debugPrint('REMOVE ME ========================= 222');
return;
}
if (type != '') {
- evt['x'] = 0;
- evt['y'] = 0;
+ evt['x'] = '0';
+ evt['y'] = '0';
} else {
evt['x'] = '${pos.x}';
evt['y'] = '${pos.y}';
@@ -689,6 +691,7 @@ class InputModel {
kForwardMouseButton: 'forward'
};
evt['buttons'] = mapButtons[evt['buttons']] ?? '';
+ debugPrint('REMOVE ME ========================= 333 $evt');
bind.sessionSendMouse(sessionId: sessionId, msg: json.encode(modify(evt)));
}
diff --git a/src/server/connection.rs b/src/server/connection.rs
index f107d15a6..ef8864499 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -1546,9 +1546,7 @@ impl Connection {
match msg.union {
Some(message::Union::MouseEvent(me)) => {
#[cfg(any(target_os = "android", target_os = "ios"))]
- if let Err(e) =
- call_main_service_pointer_input("mouse", me.mask, me.x, me.y)
- {
+ if let Err(e) = call_main_service_pointer_input("mouse", me.mask, me.x, me.y) {
log::debug!("call_main_service_pointer_input fail:{}", e);
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
@@ -1582,12 +1580,7 @@ impl Connection {
)
}
Some(touch_event::Union::PanEnd(pan_end)) => {
- call_main_service_pointer_input(
- "touch",
- 6,
- pan_end.x,
- pan_end.y,
- )
+ call_main_service_pointer_input("touch", 6, pan_end.x, pan_end.y)
}
_ => Ok(()),
},
From be982d95ea548baeee37d805e198b67a2b97da8a Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 08:37:18 +0800
Subject: [PATCH 12/75] tmp build
Signed-off-by: dignow
---
.../src/main/kotlin/com/carriez/flutter_hbb/InputService.kt | 2 ++
flutter/lib/models/input_model.dart | 6 +-----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
index 8e14a590d..84ef31793 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
@@ -190,8 +190,10 @@ class InputService : AccessibilityService() {
startGesture(mouseX, mouseY)
}
TOUCH_PAN_END -> {
+ endGesture(mouseX, mouseY)
mouseX = x * SCREEN_INFO.scale
mouseY = y * SCREEN_INFO.scale
+ continueGesture(mouseX, mouseY)
endGesture(mouseX, mouseY)
}
else -> {}
diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart
index eaff4ed6a..971bbb7e5 100644
--- a/flutter/lib/models/input_model.dart
+++ b/flutter/lib/models/input_model.dart
@@ -379,8 +379,7 @@ class InputModel {
var x = delta.dx.toInt();
var y = delta.dy.toInt();
- if (peerPlatform == kPeerPlatformLinux ||
- peerPlatform == kPeerPlatformAndroid) {
+ if (peerPlatform == kPeerPlatformLinux) {
_trackpadScrollUnsent += (delta * _trackpadSpeed);
x = _trackpadScrollUnsent.dx.truncate();
y = _trackpadScrollUnsent.dy.truncate();
@@ -638,7 +637,6 @@ class InputModel {
Offset offset, {
bool onExit = false,
}) {
- debugPrint('REMOVE ME ========================= 111');
double x = offset.dx;
double y = max(0.0, offset.dy);
if (_checkPeerControlProtected(x, y)) {
@@ -672,7 +670,6 @@ class InputModel {
buttons: evt['buttons'],
);
if (pos == null) {
- debugPrint('REMOVE ME ========================= 222');
return;
}
if (type != '') {
@@ -691,7 +688,6 @@ class InputModel {
kForwardMouseButton: 'forward'
};
evt['buttons'] = mapButtons[evt['buttons']] ?? '';
- debugPrint('REMOVE ME ========================= 333 $evt');
bind.sessionSendMouse(sessionId: sessionId, msg: json.encode(modify(evt)));
}
From 5f7055e28286174440f7a8ee17ff7bec0d600af2 Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 13:57:57 +0800
Subject: [PATCH 13/75] debug
Signed-off-by: dignow
---
.../src/main/kotlin/com/carriez/flutter_hbb/InputService.kt | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
index 84ef31793..65b7931db 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
@@ -180,8 +180,8 @@ class InputService : AccessibilityService() {
val y = max(0, _y)
when (mask) {
TOUCH_PAN_UPDATE -> {
- mouseX += x * SCREEN_INFO.scale
- mouseY += y * SCREEN_INFO.scale
+ mouseX -= x * SCREEN_INFO.scale
+ mouseY -= y * SCREEN_INFO.scale
continueGesture(mouseX, mouseY)
}
TOUCH_PAN_START -> {
@@ -193,8 +193,6 @@ class InputService : AccessibilityService() {
endGesture(mouseX, mouseY)
mouseX = x * SCREEN_INFO.scale
mouseY = y * SCREEN_INFO.scale
- continueGesture(mouseX, mouseY)
- endGesture(mouseX, mouseY)
}
else -> {}
}
From 072430cef5c0452b4a1ea36b243b1eddc1d0fbdd Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 14:48:00 +0800
Subject: [PATCH 14/75] debug android scroll
Signed-off-by: dignow
---
.../kotlin/com/carriez/flutter_hbb/InputService.kt | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
index 65b7931db..55c57729e 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
@@ -176,23 +176,21 @@ class InputService : AccessibilityService() {
@RequiresApi(Build.VERSION_CODES.N)
fun onTouchInput(mask: Int, _x: Int, _y: Int) {
- val x = max(0, _x)
- val y = max(0, _y)
when (mask) {
TOUCH_PAN_UPDATE -> {
- mouseX -= x * SCREEN_INFO.scale
- mouseY -= y * SCREEN_INFO.scale
+ mouseX -= _x * SCREEN_INFO.scale
+ mouseY -= _y * SCREEN_INFO.scale
continueGesture(mouseX, mouseY)
}
TOUCH_PAN_START -> {
- mouseX = x * SCREEN_INFO.scale
- mouseY = y * SCREEN_INFO.scale
+ mouseX = max(0, _x) * SCREEN_INFO.scale
+ mouseY = max(0, _y) * SCREEN_INFO.scale
startGesture(mouseX, mouseY)
}
TOUCH_PAN_END -> {
endGesture(mouseX, mouseY)
- mouseX = x * SCREEN_INFO.scale
- mouseY = y * SCREEN_INFO.scale
+ mouseX = max(0, _x) * SCREEN_INFO.scale
+ mouseY = max(0, _y) * SCREEN_INFO.scale
}
else -> {}
}
From 5b2358c97fb40978b30473b034a913c7d6137cce Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 14:49:49 +0800
Subject: [PATCH 15/75] debug android scroll
Signed-off-by: dignow
---
.../app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
index 55c57729e..203558968 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
@@ -180,6 +180,8 @@ class InputService : AccessibilityService() {
TOUCH_PAN_UPDATE -> {
mouseX -= _x * SCREEN_INFO.scale
mouseY -= _y * SCREEN_INFO.scale
+ mouseX = max(0, mouseX);
+ mouseY = max(0, mouseY);
continueGesture(mouseX, mouseY)
}
TOUCH_PAN_START -> {
From 6368ab691c47f6292e2156c2f3734fb46f45fa6e Mon Sep 17 00:00:00 2001
From: dignow
Date: Thu, 10 Aug 2023 16:08:30 +0800
Subject: [PATCH 16/75] simple refactor, move code from flutter_ffi.rs to
flutter.rs
Signed-off-by: dignow
---
src/flutter.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++++
src/flutter_ffi.rs | 40 +----------------------
2 files changed, 80 insertions(+), 39 deletions(-)
diff --git a/src/flutter.rs b/src/flutter.rs
index 52190ce2e..32be6b1c3 100644
--- a/src/flutter.rs
+++ b/src/flutter.rs
@@ -1130,6 +1130,85 @@ pub fn stop_global_event_stream(app_type: String) {
let _ = GLOBAL_EVENT_STREAM.write().unwrap().remove(&app_type);
}
+#[inline]
+fn session_send_touch_scale(
+ session_id: SessionID,
+ v: &serde_json::Value,
+ alt: bool,
+ ctrl: bool,
+ shift: bool,
+ command: bool,
+) {
+ match v.get("v").and_then(|s| s.as_i64()) {
+ Some(scale) => {
+ if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
+ session.send_touch_scale(scale as _, alt, ctrl, shift, command);
+ }
+ }
+ None => {}
+ }
+}
+
+#[inline]
+fn session_send_touch_pan(
+ session_id: SessionID,
+ v: &serde_json::Value,
+ pan_event: &str,
+ alt: bool,
+ ctrl: bool,
+ shift: bool,
+ command: bool,
+) {
+ match v.get("v") {
+ Some(v) => match (
+ v.get("x").and_then(|x| x.as_i64()),
+ v.get("y").and_then(|y| y.as_i64()),
+ ) {
+ (Some(x), Some(y)) => {
+ if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
+ session
+ .send_touch_pan_event(pan_event, x as _, y as _, alt, ctrl, shift, command);
+ }
+ }
+ _ => {}
+ },
+ _ => {}
+ }
+}
+
+fn session_send_touch_event(
+ session_id: SessionID,
+ v: &serde_json::Value,
+ alt: bool,
+ ctrl: bool,
+ shift: bool,
+ command: bool,
+) {
+ match v.get("t").and_then(|t| t.as_str()) {
+ Some("scale") => session_send_touch_scale(session_id, v, alt, ctrl, shift, command),
+ Some(pan_event) => {
+ session_send_touch_pan(session_id, v, pan_event, alt, ctrl, shift, command)
+ }
+ _ => {}
+ }
+}
+
+pub fn session_send_pointer(session_id: SessionID, msg: String) {
+ if let Ok(m) = serde_json::from_str::>(&msg) {
+ let alt = m.get("alt").is_some();
+ let ctrl = m.get("ctrl").is_some();
+ let shift = m.get("shift").is_some();
+ let command = m.get("command").is_some();
+ match (m.get("k"), m.get("v")) {
+ (Some(k), Some(v)) => match k.as_str() {
+ Some("touch") => session_send_touch_event(session_id, v, alt, ctrl, shift, command),
+ _ => {}
+ },
+ _ => {}
+ }
+ }
+}
+
#[no_mangle]
unsafe extern "C" fn get_rgba() {}
diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs
index c6f8ca774..34a1b61e3 100644
--- a/src/flutter_ffi.rs
+++ b/src/flutter_ffi.rs
@@ -1172,45 +1172,7 @@ pub fn main_clear_ab() {
}
pub fn session_send_pointer(session_id: SessionID, msg: String) {
- if let Ok(m) = serde_json::from_str::>(&msg) {
- let alt = m.get("alt").is_some();
- let ctrl = m.get("ctrl").is_some();
- let shift = m.get("shift").is_some();
- let command = m.get("command").is_some();
- match (m.get("k"), m.get("v")) {
- (Some(k), Some(v)) => match k.as_str() {
- Some("touch") => match v.get("t").and_then(|t| t.as_str()) {
- Some("scale") => match v.get("v").and_then(|s| s.as_i64()) {
- Some(scale) => {
- if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
- session.send_touch_scale(scale as _, alt, ctrl, shift, command);
- }
- }
- None => {}
- },
- Some(pan_event) => match v.get("v") {
- Some(v) => match (
- v.get("x").and_then(|x| x.as_i64()),
- v.get("y").and_then(|y| y.as_i64()),
- ) {
- (Some(x), Some(y)) => {
- if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
- session.send_touch_pan_event(
- pan_event, x as _, y as _, alt, ctrl, shift, command,
- );
- }
- }
- _ => {}
- },
- _ => {}
- },
- _ => {}
- },
- _ => {}
- },
- _ => {}
- }
- }
+ super::flutter::session_send_pointer(session_id, msg);
}
pub fn session_send_mouse(session_id: SessionID, msg: String) {
From e205577145d52e2174a7bdc76d12b30123fa5e18 Mon Sep 17 00:00:00 2001
From: dignow
Date: Mon, 14 Aug 2023 18:28:31 +0800
Subject: [PATCH 17/75] refact, tab to window, flutter data, init commit
Signed-off-by: dignow
---
flutter/lib/consts.dart | 2 +
.../lib/desktop/pages/remote_tab_page.dart | 34 ++++++++-
flutter/lib/models/model.dart | 50 +++++++++++++-
flutter/lib/utils/multi_window_manager.dart | 69 ++++++++++++-------
4 files changed, 127 insertions(+), 28 deletions(-)
diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart
index b3ec3aa9d..0621bc807 100644
--- a/flutter/lib/consts.dart
+++ b/flutter/lib/consts.dart
@@ -5,6 +5,7 @@ import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/models/state_model.dart';
const double kDesktopRemoteTabBarHeight = 28.0;
+const int kInvalidWindowId = -1;
const int kMainWindowId = 0;
const String kPeerPlatformWindows = "Windows";
@@ -39,6 +40,7 @@ const String kWindowEventGetSessionIdList = "get_session_id_list";
const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window";
const String kWindowEventCloseForSeparateWindow = "close_for_separate_window";
+const String kWindowEventSendNewWindowData = "send_new_window_data";
const String kOptionOpenNewConnInTabs = "enable-open-new-connections-in-tabs";
const String kOptionOpenInTabs = "allow-open-in-tabs";
diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart
index 3762a2b52..01f4e5ca0 100644
--- a/flutter/lib/desktop/pages/remote_tab_page.dart
+++ b/flutter/lib/desktop/pages/remote_tab_page.dart
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/common/shared_state.dart';
import 'package:flutter_hbb/consts.dart';
+import 'package:flutter_hbb/models/model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/desktop/pages/remote_page.dart';
import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart';
@@ -148,9 +149,40 @@ class _ConnectionTabPageState extends State {
.toList()
.join(';');
} else if (call.method == kWindowEventCloseForSeparateWindow) {
- final peerId = call.arguments;
+ debugPrint('REMOVE ME ============================= ${call.arguments}');
+ final peerId = call.arguments['peerId'];
+ final newWindowId = call.arguments['newWindowId'];
+ late RemotePage page;
+ try {
+ page = tabController.state.value.tabs.firstWhere((tab) {
+ return tab.key == peerId;
+ }).page as RemotePage;
+ } catch (e) {
+ debugPrint('Failed to find tab for peerId $peerId');
+ return false;
+ }
+ final sendRes = await rustDeskWinManager.call(
+ newWindowId,
+ kWindowEventSendNewWindowData,
+ page.ffi.ffiModel.cachedPeerData) as bool;
+ if (!sendRes) {
+ return false;
+ }
+ // Pass the required data to new window.
closeSessionOnDispose[peerId] = false;
tabController.closeBy(peerId);
+ return true;
+ } else if (call.method == kWindowEventSendNewWindowData) {
+ if (peerId == null) {
+ return false;
+ }
+ if (tabController.state.value.tabs.isEmpty) {
+ return false;
+ }
+ final page = tabController.state.value.tabs[0].page as RemotePage;
+ page.ffi.ffiModel
+ .handleCachedPeerData(call.arguments as CachedPeerData, peerId!);
+ return true;
}
_update_remote_count();
});
diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart
index 4dc17f9c2..286e89a39 100644
--- a/flutter/lib/models/model.dart
+++ b/flutter/lib/models/model.dart
@@ -41,7 +41,19 @@ final _waitForImageDialogShow = {};
final _waitForFirstImage = {};
final _constSessionId = Uuid().v4obj();
+class CachedPeerData {
+ Map updatePrivacyMode = {};
+ Map peerInfo = {};
+ List> cursorDataList = [];
+ Map lastCursorId = {};
+ bool secure = false;
+ bool direct = false;
+
+ CachedPeerData();
+}
+
class FfiModel with ChangeNotifier {
+ CachedPeerData cachedPeerData = CachedPeerData();
PeerInfo _pi = PeerInfo();
Display _display = Display();
@@ -117,6 +129,8 @@ class FfiModel with ChangeNotifier {
}
setConnectionType(String peerId, bool secure, bool direct) {
+ cachedPeerData.secure = secure;
+ cachedPeerData.direct = direct;
_secure = secure;
_direct = direct;
try {
@@ -143,6 +157,22 @@ class FfiModel with ChangeNotifier {
_permissions.clear();
}
+ handleCachedPeerData(CachedPeerData data, String peerId) async {
+ handleMsgBox({
+ 'type': 'success',
+ 'title': 'Successful',
+ 'text': 'Connected, waiting for image...',
+ 'link': '',
+ }, sessionId, peerId);
+ updatePrivacyMode(data.updatePrivacyMode, sessionId, peerId);
+ setConnectionType(peerId, data.secure, data.direct);
+ handlePeerInfo(data.peerInfo, peerId);
+ for (var element in data.cursorDataList) {
+ handleCursorData(element);
+ }
+ handleCursorId(data.lastCursorId);
+ }
+
// todo: why called by two position
StreamEventHandler startEventListener(SessionID sessionId, String peerId) {
return (evt) async {
@@ -159,9 +189,9 @@ class FfiModel with ChangeNotifier {
} else if (name == 'switch_display') {
handleSwitchDisplay(evt, sessionId, peerId);
} else if (name == 'cursor_data') {
- await parent.target?.cursorModel.updateCursorData(evt);
+ await handleCursorData(evt);
} else if (name == 'cursor_id') {
- await parent.target?.cursorModel.updateCursorId(evt);
+ await handleCursorId(evt);
} else if (name == 'cursor_position') {
await parent.target?.cursorModel.updateCursorPosition(evt, peerId);
} else if (name == 'clipboard') {
@@ -453,6 +483,8 @@ class FfiModel with ChangeNotifier {
/// Handle the peer info event based on [evt].
handlePeerInfo(Map evt, String peerId) async {
+ cachedPeerData.peerInfo = evt;
+
// recent peer updated by handle_peer_info(ui_session_interface.rs) --> handle_peer_info(client.rs) --> save_config(client.rs)
bind.mainLoadRecentPeers();
@@ -568,9 +600,20 @@ class FfiModel with ChangeNotifier {
return d;
}
+ handleCursorId(Map evt) async {
+ cachedPeerData.lastCursorId = evt;
+ await parent.target?.cursorModel.updateCursorId(evt);
+ }
+
+ handleCursorData(Map evt) async {
+ cachedPeerData.cursorDataList.add(evt);
+ await parent.target?.cursorModel.updateCursorData(evt);
+ }
+
/// Handle the peer info synchronization event based on [evt].
handleSyncPeerInfo(Map evt, SessionID sessionId) async {
if (evt['displays'] != null) {
+ cachedPeerData.peerInfo['displays'] = evt['displays'];
List displays = json.decode(evt['displays']);
List newDisplays = [];
for (int i = 0; i < displays.length; ++i) {
@@ -1667,7 +1710,8 @@ class FFI {
stream.listen((message) {
if (closed) return;
if (isSessionAdded && !isToNewWindowNotified.value) {
- bind.sessionReadyToNewWindow(sessionId: sessionId);
+ // bind.sessionReadyToNewWindow(sessionId: sessionId);
+ bind.sessionRefresh(sessionId: sessionId);
isToNewWindowNotified.value = true;
}
() async {
diff --git a/flutter/lib/utils/multi_window_manager.dart b/flutter/lib/utils/multi_window_manager.dart
index 3f7d995b7..4230182d6 100644
--- a/flutter/lib/utils/multi_window_manager.dart
+++ b/flutter/lib/utils/multi_window_manager.dart
@@ -28,6 +28,13 @@ extension Index on int {
}
}
+class MultiWindowCallResult {
+ int windowId;
+ dynamic result;
+
+ MultiWindowCallResult(this.windowId, this.result);
+}
+
/// Window Manager
/// mainly use it in `Main Window`
/// use it in sub window is not recommended
@@ -49,7 +56,10 @@ class RustDeskMultiWindowManager {
'id': peerId,
'session_id': sessionId,
};
- await _newSession(
+ // It's better to use the window id that returned by _newSession.
+ // Do not pass original window id to _newSession,
+ // as this function cann't promise the necessary data is passed to new window.
+ final multiWindowRes = await _newSession(
false,
WindowType.RemoteDesktop,
kWindowEventNewRemoteDesktop,
@@ -57,17 +67,21 @@ class RustDeskMultiWindowManager {
_remoteDesktopWindows,
jsonEncode(params),
);
+ // kWindowEventCloseForSeparateWindow will not only close the tab, but also pass the required data to new window.
await DesktopMultiWindow.invokeMethod(
- windowId, kWindowEventCloseForSeparateWindow, peerId);
+ windowId, kWindowEventCloseForSeparateWindow, {
+ 'peerId': peerId,
+ 'newWindowId': multiWindowRes.windowId,
+ });
}
- newSessionWindow(
+ Future newSessionWindow(
WindowType type, String remoteId, String msg, List windows) async {
final windowController = await DesktopMultiWindow.createWindow(msg);
+ final windowId = windowController.windowId;
windowController
- ..setFrame(const Offset(0, 0) &
- Size(1280 + windowController.windowId * 20,
- 720 + windowController.windowId * 20))
+ ..setFrame(
+ const Offset(0, 0) & Size(1280 + windowId * 20, 720 + windowId * 20))
..center()
..setTitle(getWindowNameWithId(
remoteId,
@@ -76,11 +90,12 @@ class RustDeskMultiWindowManager {
if (Platform.isMacOS) {
Future.microtask(() => windowController.show());
}
- registerActiveWindow(windowController.windowId);
- windows.add(windowController.windowId);
+ registerActiveWindow(windowId);
+ windows.add(windowId);
+ return windowId;
}
- _newSession(
+ Future _newSession(
bool openInTabs,
WindowType type,
String methodName,
@@ -90,9 +105,10 @@ class RustDeskMultiWindowManager {
) async {
if (openInTabs) {
if (windows.isEmpty) {
- await newSessionWindow(type, remoteId, msg, windows);
+ final windowId = await newSessionWindow(type, remoteId, msg, windows);
+ return MultiWindowCallResult(windowId, null);
} else {
- call(type, methodName, msg);
+ return call(type, methodName, msg);
}
} else {
if (_inactiveWindows.isNotEmpty) {
@@ -103,15 +119,16 @@ class RustDeskMultiWindowManager {
await DesktopMultiWindow.invokeMethod(windowId, methodName, msg);
WindowController.fromWindowId(windowId).show();
registerActiveWindow(windowId);
- return;
+ return MultiWindowCallResult(windowId, null);
}
}
}
- await newSessionWindow(type, remoteId, msg, windows);
+ final windowId = await newSessionWindow(type, remoteId, msg, windows);
+ return MultiWindowCallResult(windowId, null);
}
}
- Future newSession(
+ Future newSession(
WindowType type,
String methodName,
String remoteId,
@@ -143,15 +160,15 @@ class RustDeskMultiWindowManager {
for (final windowId in windows) {
if (await DesktopMultiWindow.invokeMethod(
windowId, kWindowEventActiveSession, remoteId)) {
- return;
+ return MultiWindowCallResult(windowId, null);
}
}
}
- await _newSession(openInTabs, type, methodName, remoteId, windows, msg);
+ return _newSession(openInTabs, type, methodName, remoteId, windows, msg);
}
- Future newRemoteDesktop(
+ Future newRemoteDesktop(
String remoteId, {
String? password,
String? switchUuid,
@@ -168,7 +185,7 @@ class RustDeskMultiWindowManager {
);
}
- Future newFileTransfer(String remoteId,
+ Future newFileTransfer(String remoteId,
{String? password, bool? forceRelay}) async {
return await newSession(
WindowType.FileTransfer,
@@ -180,7 +197,7 @@ class RustDeskMultiWindowManager {
);
}
- Future newPortForward(String remoteId, bool isRDP,
+ Future newPortForward(String remoteId, bool isRDP,
{String? password, bool? forceRelay}) async {
return await newSession(
WindowType.PortForward,
@@ -193,18 +210,22 @@ class RustDeskMultiWindowManager {
);
}
- Future call(WindowType type, String methodName, dynamic args) async {
+ Future call(
+ WindowType type, String methodName, dynamic args) async {
final wnds = _findWindowsByType(type);
if (wnds.isEmpty) {
- return;
+ return MultiWindowCallResult(kInvalidWindowId, null);
}
for (final windowId in wnds) {
if (_activeWindows.contains(windowId)) {
- return await DesktopMultiWindow.invokeMethod(
- windowId, methodName, args);
+ final res =
+ await DesktopMultiWindow.invokeMethod(windowId, methodName, args);
+ return MultiWindowCallResult(windowId, res);
}
}
- return await DesktopMultiWindow.invokeMethod(wnds[0], methodName, args);
+ final res =
+ await DesktopMultiWindow.invokeMethod(wnds[0], methodName, args);
+ return MultiWindowCallResult(wnds[0], res);
}
List _findWindowsByType(WindowType type) {
From fad88c27189a0cd9f5b93f19240991e66e95cc5f Mon Sep 17 00:00:00 2001
From: dignow
Date: Mon, 14 Aug 2023 20:40:58 +0800
Subject: [PATCH 18/75] refact, tab to window, remove rust cache data
Signed-off-by: dignow
---
flutter/lib/consts.dart | 3 +-
.../desktop/pages/desktop_setting_page.dart | 1 -
flutter/lib/desktop/pages/remote_page.dart | 5 +-
.../lib/desktop/pages/remote_tab_page.dart | 49 +++++----------
.../lib/desktop/widgets/remote_toolbar.dart | 2 +-
.../lib/models/desktop_render_texture.dart | 8 +--
flutter/lib/models/model.dart | 63 ++++++++++++++++---
flutter/lib/utils/multi_window_manager.dart | 12 +---
src/client.rs | 2 +-
src/client/io_loop.rs | 49 +--------------
src/flutter.rs | 8 ++-
src/flutter_ffi.rs | 8 ---
src/port_forward.rs | 2 +-
src/ui_cm_interface.rs | 1 +
src/ui_session_interface.rs | 43 ++-----------
15 files changed, 100 insertions(+), 156 deletions(-)
diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart
index 0621bc807..25c3e16a1 100644
--- a/flutter/lib/consts.dart
+++ b/flutter/lib/consts.dart
@@ -39,8 +39,7 @@ const String kWindowEventGetRemoteList = "get_remote_list";
const String kWindowEventGetSessionIdList = "get_session_id_list";
const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window";
-const String kWindowEventCloseForSeparateWindow = "close_for_separate_window";
-const String kWindowEventSendNewWindowData = "send_new_window_data";
+const String kWindowEventGetCachedSessionData = "get_cached_session_data";
const String kOptionOpenNewConnInTabs = "enable-open-new-connections-in-tabs";
const String kOptionOpenInTabs = "allow-open-in-tabs";
diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart
index b868042a4..8d5ddb7dc 100644
--- a/flutter/lib/desktop/pages/desktop_setting_page.dart
+++ b/flutter/lib/desktop/pages/desktop_setting_page.dart
@@ -17,7 +17,6 @@ import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
-import 'package:window_manager/window_manager.dart';
import '../../common/widgets/dialog.dart';
import '../../common/widgets/login.dart';
diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart
index 28212e4ca..2daffaccf 100644
--- a/flutter/lib/desktop/pages/remote_page.dart
+++ b/flutter/lib/desktop/pages/remote_page.dart
@@ -35,6 +35,7 @@ class RemotePage extends StatefulWidget {
Key? key,
required this.id,
required this.sessionId,
+ required this.tabWindowId,
required this.password,
required this.toolbarState,
required this.tabController,
@@ -44,6 +45,7 @@ class RemotePage extends StatefulWidget {
final String id;
final SessionID? sessionId;
+ final int? tabWindowId;
final String? password;
final ToolbarState toolbarState;
final String? switchUuid;
@@ -106,6 +108,7 @@ class _RemotePageState extends State
password: widget.password,
switchUuid: widget.switchUuid,
forceRelay: widget.forceRelay,
+ tabWindowId: widget.tabWindowId,
);
WidgetsBinding.instance.addPostFrameCallback((_) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
@@ -204,7 +207,7 @@ class _RemotePageState extends State
// https://github.com/flutter/flutter/issues/64935
super.dispose();
debugPrint("REMOTE PAGE dispose session $sessionId ${widget.id}");
- await _renderTexture.destroy();
+ await _renderTexture.destroy(widget.tabWindowId != null);
// ensure we leave this session, this is a double check
bind.sessionEnterOrLeave(sessionId: sessionId, enter: false);
DesktopMultiWindow.removeListener(this);
diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart
index 01f4e5ca0..51bcec51d 100644
--- a/flutter/lib/desktop/pages/remote_tab_page.dart
+++ b/flutter/lib/desktop/pages/remote_tab_page.dart
@@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/common/shared_state.dart';
import 'package:flutter_hbb/consts.dart';
-import 'package:flutter_hbb/models/model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/desktop/pages/remote_page.dart';
import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart';
@@ -56,6 +55,7 @@ class _ConnectionTabPageState extends State {
RemoteCountState.init();
peerId = params['id'];
final sessionId = params['session_id'];
+ final tabWindowId = params['tab_window_id'];
if (peerId != null) {
ConnectionTypeState.init(peerId!);
tabController.onSelected = (id) {
@@ -78,6 +78,7 @@ class _ConnectionTabPageState extends State {
key: ValueKey(peerId),
id: peerId!,
sessionId: sessionId == null ? null : SessionID(sessionId),
+ tabWindowId: tabWindowId,
password: params['password'],
toolbarState: _toolbarState,
tabController: tabController,
@@ -99,12 +100,14 @@ class _ConnectionTabPageState extends State {
print(
"[Remote Page] call ${call.method} with args ${call.arguments} from window $fromWindowId");
+ dynamic returnValue;
// for simplify, just replace connectionId
if (call.method == kWindowEventNewRemoteDesktop) {
final args = jsonDecode(call.arguments);
final id = args['id'];
final switchUuid = args['switch_uuid'];
final sessionId = args['session_id'];
+ final tabWindowId = args['tab_window_id'];
windowOnTop(windowId());
ConnectionTypeState.init(id);
_toolbarState.setShow(
@@ -119,6 +122,7 @@ class _ConnectionTabPageState extends State {
key: ValueKey(id),
id: id,
sessionId: sessionId == null ? null : SessionID(sessionId),
+ tabWindowId: tabWindowId,
password: args['password'],
toolbarState: _toolbarState,
tabController: tabController,
@@ -148,43 +152,24 @@ class _ConnectionTabPageState extends State {
.map((e) => '${e.key},${(e.page as RemotePage).ffi.sessionId}')
.toList()
.join(';');
- } else if (call.method == kWindowEventCloseForSeparateWindow) {
- debugPrint('REMOVE ME ============================= ${call.arguments}');
- final peerId = call.arguments['peerId'];
- final newWindowId = call.arguments['newWindowId'];
- late RemotePage page;
+ } else if (call.method == kWindowEventGetCachedSessionData) {
+ // Ready to show new window and close old tab.
+ final peerId = call.arguments;
try {
- page = tabController.state.value.tabs.firstWhere((tab) {
- return tab.key == peerId;
- }).page as RemotePage;
+ final remotePage = tabController.state.value.tabs
+ .firstWhere((tab) => tab.key == peerId)
+ .page as RemotePage;
+ returnValue = remotePage.ffi.ffiModel.cachedPeerData.toString();
} catch (e) {
- debugPrint('Failed to find tab for peerId $peerId');
- return false;
+ debugPrint('Failed to get cached session data: $e');
}
- final sendRes = await rustDeskWinManager.call(
- newWindowId,
- kWindowEventSendNewWindowData,
- page.ffi.ffiModel.cachedPeerData) as bool;
- if (!sendRes) {
- return false;
+ if (returnValue != null) {
+ closeSessionOnDispose[peerId] = false;
+ tabController.closeBy(peerId);
}
- // Pass the required data to new window.
- closeSessionOnDispose[peerId] = false;
- tabController.closeBy(peerId);
- return true;
- } else if (call.method == kWindowEventSendNewWindowData) {
- if (peerId == null) {
- return false;
- }
- if (tabController.state.value.tabs.isEmpty) {
- return false;
- }
- final page = tabController.state.value.tabs[0].page as RemotePage;
- page.ffi.ffiModel
- .handleCachedPeerData(call.arguments as CachedPeerData, peerId!);
- return true;
}
_update_remote_count();
+ return returnValue;
});
Future.delayed(Duration.zero, () {
restoreWindowPosition(
diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart
index 6a72fc3a1..9d6dec496 100644
--- a/flutter/lib/desktop/widgets/remote_toolbar.dart
+++ b/flutter/lib/desktop/widgets/remote_toolbar.dart
@@ -771,7 +771,7 @@ class ScreenAdjustor {
updateScreen() async {
final v = await rustDeskWinManager.call(
WindowType.Main, kWindowGetWindowInfo, '');
- final String valueStr = v;
+ final String valueStr = v.result;
if (valueStr.isEmpty) {
_screen = null;
} else {
diff --git a/flutter/lib/models/desktop_render_texture.dart b/flutter/lib/models/desktop_render_texture.dart
index f59373623..f8456e339 100644
--- a/flutter/lib/models/desktop_render_texture.dart
+++ b/flutter/lib/models/desktop_render_texture.dart
@@ -1,4 +1,3 @@
-import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:texture_rgba_renderer/texture_rgba_renderer.dart';
@@ -21,7 +20,6 @@ class RenderTexture {
_sessionId = sessionId;
textureRenderer.createTexture(_textureKey).then((id) async {
- debugPrint("id: $id, texture_key: $_textureKey");
if (id != -1) {
final ptr = await textureRenderer.getTexturePtr(_textureKey);
platformFFI.registerTexture(sessionId, ptr);
@@ -31,9 +29,11 @@ class RenderTexture {
}
}
- destroy() async {
+ destroy(bool unregisterTexture) async {
if (useTextureRender && _textureKey != -1 && _sessionId != null) {
- platformFFI.registerTexture(_sessionId!, 0);
+ if (unregisterTexture) {
+ platformFFI.registerTexture(_sessionId!, 0);
+ }
await textureRenderer.closeTexture(_textureKey);
_textureKey = -1;
}
diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart
index 286e89a39..4d0e30e3e 100644
--- a/flutter/lib/models/model.dart
+++ b/flutter/lib/models/model.dart
@@ -4,6 +4,7 @@ import 'dart:io';
import 'dart:math';
import 'dart:ui' as ui;
+import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hbb/consts.dart';
@@ -50,6 +51,37 @@ class CachedPeerData {
bool direct = false;
CachedPeerData();
+
+ @override
+ String toString() {
+ return jsonEncode({
+ 'updatePrivacyMode': updatePrivacyMode,
+ 'peerInfo': peerInfo,
+ 'cursorDataList': cursorDataList,
+ 'lastCursorId': lastCursorId,
+ 'secure': secure,
+ 'direct': direct,
+ });
+ }
+
+ static CachedPeerData? fromString(String s) {
+ try {
+ final map = jsonDecode(s);
+ final data = CachedPeerData();
+ data.updatePrivacyMode = map['updatePrivacyMode'];
+ data.peerInfo = map['peerInfo'];
+ for (final cursorData in map['cursorDataList']) {
+ data.cursorDataList.add(cursorData);
+ }
+ data.lastCursorId = map['lastCursorId'];
+ data.secure = map['secure'];
+ data.direct = map['direct'];
+ return data;
+ } catch (e) {
+ debugPrint('Failed to parse CachedPeerData: $e');
+ return null;
+ }
+ }
}
class FfiModel with ChangeNotifier {
@@ -1628,7 +1660,6 @@ class FFI {
/// dialogManager use late to ensure init after main page binding [globalKey]
late final dialogManager = OverlayDialogManager();
- late final bool isSessionAdded;
late final SessionID sessionId;
late final ImageModel imageModel; // session
late final FfiModel ffiModel; // session
@@ -1647,7 +1678,6 @@ class FFI {
late final ElevationModel elevationModel; // session
FFI(SessionID? sId) {
- isSessionAdded = sId != null;
sessionId = sId ?? (isDesktop ? Uuid().v4obj() : _constSessionId);
imageModel = ImageModel(WeakReference(this));
ffiModel = FfiModel(WeakReference(this));
@@ -1673,7 +1703,8 @@ class FFI {
bool isRdp = false,
String? switchUuid,
String? password,
- bool? forceRelay}) {
+ bool? forceRelay,
+ int? tabWindowId}) {
closed = false;
auditNote = '';
assert(!(isFileTransfer && isPortForward), 'more than one connect type');
@@ -1688,7 +1719,9 @@ class FFI {
imageModel.id = id;
cursorModel.id = id;
}
- if (!isSessionAdded) {
+ // If tabWindowId != null, this session is a "tab -> window" one.
+ // Else this session is a new one.
+ if (tabWindowId == null) {
// ignore: unused_local_variable
final addRes = bind.sessionAddSync(
sessionId: sessionId,
@@ -1709,9 +1742,25 @@ class FFI {
// Preserved for the rgba data.
stream.listen((message) {
if (closed) return;
- if (isSessionAdded && !isToNewWindowNotified.value) {
- // bind.sessionReadyToNewWindow(sessionId: sessionId);
- bind.sessionRefresh(sessionId: sessionId);
+ if (tabWindowId != null && !isToNewWindowNotified.value) {
+ // Session is read to be moved to a new window.
+ // Get the cached data and handle the cached data.
+ Future.delayed(Duration.zero, () async {
+ final cachedData = await DesktopMultiWindow.invokeMethod(
+ tabWindowId, kWindowEventGetCachedSessionData, id);
+ if (cachedData == null) {
+ // unreachable
+ debugPrint('Unreachable, the cached data is empty.');
+ return;
+ }
+ final data = CachedPeerData.fromString(cachedData);
+ if (data == null) {
+ debugPrint('Unreachable, the cached data cannot be decoded.');
+ return;
+ }
+ ffiModel.handleCachedPeerData(data, id);
+ await bind.sessionRefresh(sessionId: sessionId);
+ });
isToNewWindowNotified.value = true;
}
() async {
diff --git a/flutter/lib/utils/multi_window_manager.dart b/flutter/lib/utils/multi_window_manager.dart
index 4230182d6..a8be78c74 100644
--- a/flutter/lib/utils/multi_window_manager.dart
+++ b/flutter/lib/utils/multi_window_manager.dart
@@ -54,12 +54,10 @@ class RustDeskMultiWindowManager {
var params = {
'type': WindowType.RemoteDesktop.index,
'id': peerId,
+ 'tab_window_id': windowId,
'session_id': sessionId,
};
- // It's better to use the window id that returned by _newSession.
- // Do not pass original window id to _newSession,
- // as this function cann't promise the necessary data is passed to new window.
- final multiWindowRes = await _newSession(
+ await _newSession(
false,
WindowType.RemoteDesktop,
kWindowEventNewRemoteDesktop,
@@ -67,12 +65,6 @@ class RustDeskMultiWindowManager {
_remoteDesktopWindows,
jsonEncode(params),
);
- // kWindowEventCloseForSeparateWindow will not only close the tab, but also pass the required data to new window.
- await DesktopMultiWindow.invokeMethod(
- windowId, kWindowEventCloseForSeparateWindow, {
- 'peerId': peerId,
- 'newWindowId': multiWindowRes.windowId,
- });
}
Future newSessionWindow(
diff --git a/src/client.rs b/src/client.rs
index 84f338c63..798550467 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -2366,7 +2366,7 @@ pub trait Interface: Send + Clone + 'static + Sized {
fn send(&self, data: Data);
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str);
fn handle_login_error(&mut self, err: &str) -> bool;
- fn handle_peer_info(&mut self, pi: PeerInfo, is_cached_pi: bool);
+ fn handle_peer_info(&mut self, pi: PeerInfo);
fn on_error(&self, err: &str) {
self.msgbox("error", "Error", err, "");
}
diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs
index 9e78b17a5..aaf426e28 100644
--- a/src/client/io_loop.rs
+++ b/src/client/io_loop.rs
@@ -125,18 +125,7 @@ impl Remote {
.await
{
Ok((mut peer, direct, pk)) => {
- let is_secured = peer.is_secured();
- #[cfg(feature = "flutter")]
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- {
- self.handler
- .cache_flutter
- .write()
- .unwrap()
- .is_secured_direct
- .replace((is_secured, direct));
- }
- self.handler.set_connection_type(is_secured, direct); // flutter -> connection_ready
+ self.handler.set_connection_type(peer.is_secured(), direct); // flutter -> connection_ready
self.handler.update_direct(Some(direct));
if conn_type == ConnType::DEFAULT_CONN {
self.handler
@@ -1021,12 +1010,7 @@ impl Remote {
}
}
Some(login_response::Union::PeerInfo(pi)) => {
- #[cfg(feature = "flutter")]
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- {
- self.handler.cache_flutter.write().unwrap().pi = pi.clone();
- }
- self.handler.handle_peer_info(pi, false);
+ self.handler.handle_peer_info(pi);
#[cfg(not(feature = "flutter"))]
self.check_clipboard_file_context();
if !(self.handler.is_file_transfer() || self.handler.is_port_forward()) {
@@ -1073,22 +1057,9 @@ impl Remote {
_ => {}
},
Some(message::Union::CursorData(cd)) => {
- #[cfg(feature = "flutter")]
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- {
- let mut lock = self.handler.cache_flutter.write().unwrap();
- if !lock.cursor_data.contains_key(&cd.id) {
- lock.cursor_data.insert(cd.id, cd.clone());
- }
- }
self.handler.set_cursor_data(cd);
}
Some(message::Union::CursorId(id)) => {
- #[cfg(feature = "flutter")]
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- {
- self.handler.cache_flutter.write().unwrap().cursor_id = id;
- }
self.handler.set_cursor_id(id.to_string());
}
Some(message::Union::CursorPosition(cp)) => {
@@ -1305,16 +1276,6 @@ impl Remote {
}
}
Some(misc::Union::SwitchDisplay(s)) => {
- #[cfg(feature = "flutter")]
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- {
- self.handler
- .cache_flutter
- .write()
- .unwrap()
- .sp
- .replace(s.clone());
- }
self.handler.handle_peer_switch_display(&s);
self.video_sender.send(MediaData::Reset).ok();
if s.width > 0 && s.height > 0 {
@@ -1506,12 +1467,6 @@ impl Remote {
}
}
Some(message::Union::PeerInfo(pi)) => {
- #[cfg(feature = "flutter")]
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- {
- self.handler.cache_flutter.write().unwrap().pi.displays =
- pi.displays.clone();
- }
self.handler.set_displays(&pi.displays);
}
_ => {}
diff --git a/src/flutter.rs b/src/flutter.rs
index 52190ce2e..1feb6b118 100644
--- a/src/flutter.rs
+++ b/src/flutter.rs
@@ -36,9 +36,11 @@ pub(crate) const APP_TYPE_CM: &str = "cm";
#[cfg(any(target_os = "android", target_os = "ios"))]
pub(crate) const APP_TYPE_CM: &str = "main";
-pub(crate) const APP_TYPE_DESKTOP_REMOTE: &str = "remote";
-pub(crate) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer";
-pub(crate) const APP_TYPE_DESKTOP_PORT_FORWARD: &str = "port forward";
+// Do not remove the following constants.
+// Uncomment them when they are used.
+// pub(crate) const APP_TYPE_DESKTOP_REMOTE: &str = "remote";
+// pub(crate) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer";
+// pub(crate) const APP_TYPE_DESKTOP_PORT_FORWARD: &str = "port forward";
lazy_static::lazy_static! {
pub(crate) static ref CUR_SESSION_ID: RwLock = Default::default();
diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs
index ab7acc104..c36d56665 100644
--- a/src/flutter_ffi.rs
+++ b/src/flutter_ffi.rs
@@ -597,14 +597,6 @@ pub fn session_change_resolution(session_id: SessionID, display: i32, width: i32
}
}
-pub fn session_ready_to_new_window(session_id: SessionID) {
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- if let Some(session) = SESSIONS.write().unwrap().get_mut(&session_id) {
- session.restore_flutter_cache();
- session.refresh_video();
- }
-}
-
pub fn session_set_size(_session_id: SessionID, _width: usize, _height: usize) {
#[cfg(feature = "flutter_texture_render")]
if let Some(session) = SESSIONS.write().unwrap().get_mut(&_session_id) {
diff --git a/src/port_forward.rs b/src/port_forward.rs
index 1e918cce1..6a087abe2 100644
--- a/src/port_forward.rs
+++ b/src/port_forward.rs
@@ -146,7 +146,7 @@ async fn connect_and_login(
return Ok(None);
}
Some(login_response::Union::PeerInfo(pi)) => {
- interface.handle_peer_info(pi, false);
+ interface.handle_peer_info(pi);
break;
}
_ => {}
diff --git a/src/ui_cm_interface.rs b/src/ui_cm_interface.rs
index 29828d6b7..16fa59631 100644
--- a/src/ui_cm_interface.rs
+++ b/src/ui_cm_interface.rs
@@ -325,6 +325,7 @@ impl IpcTaskRunner {
// for tmp use, without real conn id
let mut write_jobs: Vec = Vec::new();
+ #[cfg(windows)]
let is_authorized = self.cm.is_authorized(self.conn_id);
#[cfg(windows)]
diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs
index 1fdff8144..eb902e3a9 100644
--- a/src/ui_session_interface.rs
+++ b/src/ui_session_interface.rs
@@ -48,17 +48,6 @@ pub static IS_IN: AtomicBool = AtomicBool::new(false);
const CHANGE_RESOLUTION_VALID_TIMEOUT_SECS: u64 = 15;
-#[cfg(feature = "flutter")]
-#[cfg(not(any(target_os = "android", target_os = "ios")))]
-#[derive(Default)]
-pub struct CacheFlutter {
- pub pi: PeerInfo,
- pub sp: Option,
- pub cursor_data: HashMap,
- pub cursor_id: u64,
- pub is_secured_direct: Option<(bool, bool)>,
-}
-
#[derive(Clone, Default)]
pub struct Session {
pub session_id: SessionID, // different from the one in LoginConfigHandler, used for flutter UI message pass
@@ -73,9 +62,6 @@ pub struct Session {
pub server_file_transfer_enabled: Arc>,
pub server_clipboard_enabled: Arc>,
pub last_change_display: Arc>,
- #[cfg(feature = "flutter")]
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- pub cache_flutter: Arc>,
}
#[derive(Clone)]
@@ -1095,7 +1081,7 @@ impl Interface for Session {
handle_login_error(self.lc.clone(), err, self)
}
- fn handle_peer_info(&mut self, mut pi: PeerInfo, is_cached_pi: bool) {
+ fn handle_peer_info(&mut self, mut pi: PeerInfo) {
log::debug!("handle_peer_info :{:?}", pi);
pi.username = self.lc.read().unwrap().get_username(&pi);
if pi.current_display as usize >= pi.displays.len() {
@@ -1116,12 +1102,10 @@ impl Interface for Session {
self.msgbox("error", "Remote Error", "No Display", "");
return;
}
- if !is_cached_pi {
- self.try_change_init_resolution(pi.current_display);
- let p = self.lc.read().unwrap().should_auto_login();
- if !p.is_empty() {
- input_os_password(p, true, self.clone());
- }
+ self.try_change_init_resolution(pi.current_display);
+ let p = self.lc.read().unwrap().should_auto_login();
+ if !p.is_empty() {
+ input_os_password(p, true, self.clone());
}
let current = &pi.displays[pi.current_display as usize];
self.set_display(
@@ -1222,23 +1206,6 @@ impl Session {
pub fn ctrl_alt_del(&self) {
self.send_key_event(&crate::keyboard::client::event_ctrl_alt_del());
}
-
- #[cfg(feature = "flutter")]
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- pub fn restore_flutter_cache(&mut self) {
- if let Some((is_secured, direct)) = self.cache_flutter.read().unwrap().is_secured_direct {
- self.set_connection_type(is_secured, direct);
- }
- let pi = self.cache_flutter.read().unwrap().pi.clone();
- self.handle_peer_info(pi, true);
- if let Some(sp) = self.cache_flutter.read().unwrap().sp.as_ref() {
- self.handle_peer_switch_display(sp);
- }
- for (_, cd) in self.cache_flutter.read().unwrap().cursor_data.iter() {
- self.set_cursor_data(cd.clone());
- }
- self.set_cursor_id(self.cache_flutter.read().unwrap().cursor_id.to_string());
- }
}
#[tokio::main(flavor = "current_thread")]
From 9adac5686be4914134e124162694b38338c66c2a Mon Sep 17 00:00:00 2001
From: dignow
Date: Wed, 16 Aug 2023 21:52:03 +0800
Subject: [PATCH 19/75] fix unregister texture condition
Signed-off-by: dignow
---
flutter/lib/desktop/pages/remote_page.dart | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart
index 2daffaccf..0d51cabdd 100644
--- a/flutter/lib/desktop/pages/remote_page.dart
+++ b/flutter/lib/desktop/pages/remote_page.dart
@@ -207,7 +207,7 @@ class _RemotePageState extends State
// https://github.com/flutter/flutter/issues/64935
super.dispose();
debugPrint("REMOTE PAGE dispose session $sessionId ${widget.id}");
- await _renderTexture.destroy(widget.tabWindowId != null);
+ await _renderTexture.destroy(closeSession);
// ensure we leave this session, this is a double check
bind.sessionEnterOrLeave(sessionId: sessionId, enter: false);
DesktopMultiWindow.removeListener(this);
From 3cc6ba005ad7bb1676d675fbe68ad83c63d53a79 Mon Sep 17 00:00:00 2001
From: NicKoehler <53040044+NicKoehler@users.noreply.github.com>
Date: Sat, 19 Aug 2023 19:39:58 +0000
Subject: [PATCH 20/75] Update it.rs
---
src/lang/it.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lang/it.rs b/src/lang/it.rs
index f3ec2d941..4febb9e00 100644
--- a/src/lang/it.rs
+++ b/src/lang/it.rs
@@ -537,6 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Toggle Tags", "Attiva/disattiva tag"),
("pull_ab_failed_tip", "Impossibile aggiornare la rubrica"),
("push_ab_failed_tip", "Impossibile sincronizzare la rubrica con il server"),
- ("synced_peer_readded_tip", ""),
+ ("synced_peer_readded_tip", "I dispositivi presenti nelle sessioni recenti saranno sincronizzati di nuovo nella rubrica."),
].iter().cloned().collect();
}
From ee8510cec7fdedf9ae2b7370fc4db070d87c5a88 Mon Sep 17 00:00:00 2001
From: 21pages
Date: Sun, 20 Aug 2023 11:24:34 +0800
Subject: [PATCH 21/75] peer_to_map function serde password
Signed-off-by: 21pages
---
src/flutter_ffi.rs | 2 +-
src/ui_interface.rs | 16 +++++-----------
2 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs
index f076b4b23..50f1e33dc 100644
--- a/src/flutter_ffi.rs
+++ b/src/flutter_ffi.rs
@@ -895,7 +895,7 @@ pub fn main_load_recent_peers_for_ab(filter: String) -> String {
if !config::APP_DIR.read().unwrap().is_empty() {
let peers: Vec> = PeerConfig::peers(id_filters)
.drain(..)
- .map(|(id, _, p)| peer_to_map_ab(id, p))
+ .map(|(id, _, p)| peer_to_map(id, p))
.collect();
return serde_json::ser::to_string(&peers).unwrap_or("".to_owned());
}
diff --git a/src/ui_interface.rs b/src/ui_interface.rs
index 1589a4e2b..7e1b3a9bb 100644
--- a/src/ui_interface.rs
+++ b/src/ui_interface.rs
@@ -625,6 +625,7 @@ pub fn discover() {
#[cfg(feature = "flutter")]
pub fn peer_to_map(id: String, p: PeerConfig) -> HashMap<&'static str, String> {
+ use hbb_common::sodiumoxide::base64;
HashMap::<&str, String>::from_iter([
("id", id),
("username", p.info.username.clone()),
@@ -634,20 +635,13 @@ pub fn peer_to_map(id: String, p: PeerConfig) -> HashMap<&'static str, String> {
"alias",
p.options.get("alias").unwrap_or(&"".to_owned()).to_owned(),
),
+ (
+ "hash",
+ base64::encode(p.password, base64::Variant::Original),
+ ),
])
}
-#[cfg(feature = "flutter")]
-pub fn peer_to_map_ab(id: String, p: PeerConfig) -> HashMap<&'static str, String> {
- use hbb_common::sodiumoxide::base64;
- let mut m = peer_to_map(id, p.clone());
- m.insert(
- "hash",
- base64::encode(p.password, base64::Variant::Original),
- );
- m
-}
-
#[cfg(feature = "flutter")]
pub fn peer_exists(id: &str) -> bool {
PeerConfig::exists(id)
From 7ec462737b178a0671842be4d23a712682f43333 Mon Sep 17 00:00:00 2001
From: 21pages
Date: Sun, 20 Aug 2023 15:49:00 +0800
Subject: [PATCH 22/75] save ab password to recent PeerConfig when connected
with it
Signed-off-by: 21pages
---
src/client.rs | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/client.rs b/src/client.rs
index 84f338c63..7b4d052aa 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -1074,6 +1074,7 @@ pub struct LoginConfigHandler {
pub direct: Option,
pub received: bool,
switch_uuid: Option,
+ pub save_ab_password_to_recent: bool,
}
impl Deref for LoginConfigHandler {
@@ -1647,7 +1648,10 @@ impl LoginConfigHandler {
log::debug!("remember password of {}", self.id);
}
} else {
- if !password0.is_empty() {
+ if self.save_ab_password_to_recent {
+ config.password = password;
+ log::debug!("save ab password of {} to recent", self.id);
+ } else if !password0.is_empty() {
config.password = Default::default();
log::debug!("remove password of {}", self.id);
}
@@ -2173,6 +2177,7 @@ pub fn handle_login_error(
err: &str,
interface: &impl Interface,
) -> bool {
+ lc.write().unwrap().save_ab_password_to_recent = false;
if err == LOGIN_MSG_PASSWORD_EMPTY {
lc.write().unwrap().password = Default::default();
interface.msgbox("input-password", "Password Required", "", "");
@@ -2252,7 +2257,11 @@ pub async fn handle_hash(
.find_map(|p| if p.id == id { Some(p) } else { None })
{
if let Ok(hash) = base64::decode(p.hash.clone(), base64::Variant::Original) {
- password = hash;
+ if !hash.is_empty() {
+ password = hash;
+ lc.write().unwrap().save_ab_password_to_recent = true;
+ lc.write().unwrap().password = password.clone();
+ }
}
}
}
From c3abd3e2b3f2f7c7e5f366c20306724cb7c844d7 Mon Sep 17 00:00:00 2001
From: 21pages
Date: Sun, 20 Aug 2023 17:14:52 +0800
Subject: [PATCH 23/75] save user info when refreshCurrentUser
Signed-off-by: 21pages
---
flutter/lib/common/widgets/peer_tab_page.dart | 3 +--
flutter/lib/models/user_model.dart | 1 +
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/flutter/lib/common/widgets/peer_tab_page.dart b/flutter/lib/common/widgets/peer_tab_page.dart
index 259a59300..120ea7ff1 100644
--- a/flutter/lib/common/widgets/peer_tab_page.dart
+++ b/flutter/lib/common/widgets/peer_tab_page.dart
@@ -722,7 +722,6 @@ Widget _hoverAction(
);
return Obx(
() => Container(
- padding: padding,
margin: EdgeInsets.symmetric(horizontal: 1),
decoration:
(hover.value || hoverableWhenfalse?.value == false) ? deco : null,
@@ -730,6 +729,6 @@ Widget _hoverAction(
onHover: (value) => hover.value = value,
onTap: onTap,
onTapDown: onTapDown,
- child: child)),
+ child: Container(padding: padding, child: child))),
);
}
diff --git a/flutter/lib/models/user_model.dart b/flutter/lib/models/user_model.dart
index 2d8e5c61a..559e8be36 100644
--- a/flutter/lib/models/user_model.dart
+++ b/flutter/lib/models/user_model.dart
@@ -95,6 +95,7 @@ class UserModel {
_parseAndUpdateUser(UserPayload user) {
userName.value = user.name;
isAdmin.value = user.isAdmin;
+ bind.mainSetLocalOption(key: 'user_info', value: jsonEncode(user));
}
// update ab and group status
From cff872dd07b06fce9a53164218da66de6899657a Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Sun, 20 Aug 2023 21:44:13 +0800
Subject: [PATCH 24/75] arm runner
---
.github/workflows/flutter-build.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml
index 588c5457d..b0382b38b 100644
--- a/.github/workflows/flutter-build.yml
+++ b/.github/workflows/flutter-build.yml
@@ -766,7 +766,7 @@ jobs:
if: ${{ inputs.upload-artifact }}
needs: [generate-bridge-linux, build-vcpkg-deps-linux]
name: build-rust-lib ${{ matrix.job.target }} (${{ matrix.job.os }}) [${{ matrix.job.extra-build-features }}]
- runs-on: [self-hosted]
+ runs-on: [self-hosted, Linux, X64]
strategy:
fail-fast: false
matrix:
@@ -910,7 +910,7 @@ jobs:
if: ${{ inputs.upload-artifact }}
needs: [build-vcpkg-deps-linux]
name: build-rustdesk(sciter) ${{ matrix.job.target }} (${{ matrix.job.os }}) [${{ matrix.job.extra-build-features }}]
- runs-on: [self-hosted]
+ runs-on: [self-hosted, Linux, ARM64]
strategy:
fail-fast: false
matrix:
From 71f136be206153c5df43946673b54dbca338fc5b Mon Sep 17 00:00:00 2001
From: jimmyGALLAND <64364019+jimmyGALLAND@users.noreply.github.com>
Date: Sun, 20 Aug 2023 18:41:53 +0200
Subject: [PATCH 25/75] Update fr.rs
---
src/lang/fr.rs | 80 +++++++++++++++++++++++++-------------------------
1 file changed, 40 insertions(+), 40 deletions(-)
diff --git a/src/lang/fr.rs b/src/lang/fr.rs
index 18e1b1ffb..16e0585ee 100644
--- a/src/lang/fr.rs
+++ b/src/lang/fr.rs
@@ -233,7 +233,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Username missed", "Nom d'utilisateur manquant"),
("Password missed", "Mot de passe manquant"),
("Wrong credentials", "Identifiant ou mot de passe erroné"),
- ("The verification code is incorrect or has expired", ""),
+ ("The verification code is incorrect or has expired", "Le code de vérification est incorrect ou a expiré"),
("Edit Tag", "Modifier la balise"),
("Unremember Password", "Oublier le Mot de passe"),
("Favorites", "Favoris"),
@@ -303,7 +303,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Unsupported", "Non pris en charge"),
("Peer denied", "Machine distante refusée"),
("Please install plugins", "Veuillez installer les plugins"),
- ("Peer exit", ""),
+ ("Peer exit", "Machine distante déconnectée"),
("Failed to turn off", "Échec de la désactivation"),
("Turned off", "Désactivé"),
("In privacy mode", "en mode privé"),
@@ -337,8 +337,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Ratio", "Rapport"),
("Image Quality", "Qualité d'image"),
("Scroll Style", "Style de défilement"),
- ("Show Toolbar", ""),
- ("Hide Toolbar", ""),
+ ("Show Toolbar", "Afficher la barre d'outils"),
+ ("Hide Toolbar", "Masquer la barre d'outils"),
("Direct Connection", "Connexion directe"),
("Relay Connection", "Connexion relais"),
("Secure Connection", "Connexion sécurisée"),
@@ -367,8 +367,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use IP Whitelisting", "Utiliser une liste blanche d'IP"),
("Network", "Réseau"),
("Enable RDP", "Activer connection RDP"),
- ("Pin Toolbar", ""),
- ("Unpin Toolbar", ""),
+ ("Pin Toolbar", "Épingler la barre d'outil"),
+ ("Unpin Toolbar", "Détacher la barre d'outil"),
("Recording", "Enregistrement"),
("Directory", "Répertoire"),
("Automatically record incoming sessions", "Enregistrement automatique des sessions entrantes"),
@@ -460,8 +460,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", "Résolution"),
("No transfers in progress", "Pas de transfert en cours"),
("Set one-time password length", "Définir la longueur du mot de passe à usage unique"),
- ("install_cert_tip", ""),
- ("confirm_install_cert_tip", ""),
+ ("install_cert_tip", "Installer le certificat RustDesk"),
+ ("confirm_install_cert_tip", "Il s'agit d'un certificat RustDesk, auquel on peut faire confiance. Le certificat sera utilisé pour approuver et installer les pilotes RustDesk si nécessaire."),
("RDP Settings", "Configuration RDP"),
("Sort by", "Trier par"),
("New Connection", "Nouvelle connexion"),
@@ -506,37 +506,37 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable", "Activé"),
("Disable", "Desactivé"),
("Options", "Options"),
- ("resolution_original_tip", ""),
- ("resolution_fit_local_tip", ""),
- ("resolution_custom_tip", ""),
- ("Collapse toolbar", ""),
- ("Accept and Elevate", ""),
- ("accept_and_elevate_btn_tooltip", ""),
- ("clipboard_wait_response_timeout_tip", ""),
- ("Incoming connection", ""),
- ("Outgoing connection", ""),
- ("Exit", ""),
- ("Open", ""),
- ("logout_tip", ""),
- ("Service", ""),
- ("Start", ""),
- ("Stop", ""),
- ("exceed_max_devices", ""),
- ("Sync with recent sessions", ""),
- ("Sort tags", ""),
- ("Open connection in new tab", ""),
- ("Move tab to new window", ""),
- ("Can not be empty", ""),
- ("Already exists", ""),
- ("Change Password", ""),
- ("Refresh Password", ""),
- ("ID", ""),
- ("Grid View", ""),
- ("List View", ""),
- ("Select", ""),
- ("Toggle Tags", ""),
- ("pull_ab_failed_tip", ""),
- ("push_ab_failed_tip", ""),
- ("synced_peer_readded_tip", ""),
+ ("resolution_original_tip", "Résolution d'origine"),
+ ("resolution_fit_local_tip", "Adapter la résolution local"),
+ ("resolution_custom_tip", "Résolution personnalisée"),
+ ("Collapse toolbar", "Réduire la barre d'outils"),
+ ("Accept and Elevate", "Accepter et autoriser l'augmentation des privilèges"),
+ ("accept_and_elevate_btn_tooltip", "Accepter la connexion l'augmentation des privilèges UAC."),
+ ("clipboard_wait_response_timeout_tip", "Expiration du délai d'attente presse-papiers."),
+ ("Incoming connection", "Connexion entrante"),
+ ("Outgoing connection", "Connexion sortante"),
+ ("Exit", "Quitter"),
+ ("Open", "Ouvrir"),
+ ("logout_tip", "Êtes-vous sûr de vouloir vous déconnecter?"),
+ ("Service", "Service"),
+ ("Start", "Lancer"),
+ ("Stop", "Stopper"),
+ ("exceed_max_devices", "Vous avez atteint le nombre maximal d'appareils gérés."),
+ ("Sync with recent sessions", "Synchroniser avec les sessions récentes"),
+ ("Sort tags", "Trier les Tags"),
+ ("Open connection in new tab", "Ouvrir la connexion dans un nouvel onglet"),
+ ("Move tab to new window", "Déplacer l'onglet vers une nouvelle fenêtre"),
+ ("Can not be empty", "Ne peux pas être vide"),
+ ("Already exists", "Existe déjà"),
+ ("Change Password", "Changer le mot de passe"),
+ ("Refresh Password", "Actualiser le mot de passe"),
+ ("ID", "ID"),
+ ("Grid View", "Vue Grille"),
+ ("List View", "Vue Liste"),
+ ("Select", "Sélectionner"),
+ ("Toggle Tags", "Basculer vers les Tags"),
+ ("pull_ab_failed_tip", "Impossible d'actualiser le carnet d'adresses"),
+ ("push_ab_failed_tip", "Échec de la synchronisation du carnet d'adresses"),
+ ("synced_peer_readded_tip", "Les appareils qui étaient présents dans les sessions récentes seront synchronisés avec le carnet d'adresses."),
].iter().cloned().collect();
}
From b5411b686dbf801adbd68542a47d7562b374ccc6 Mon Sep 17 00:00:00 2001
From: 21pages
Date: Mon, 21 Aug 2023 08:39:47 +0800
Subject: [PATCH 26/75] recent/ab password keep same: sync connected password
to addressbook anyway, delete recent password also delete ab password
Signed-off-by: 21pages
---
flutter/lib/common/widgets/peer_card.dart | 13 ++++++-------
flutter/lib/models/ab_model.dart | 12 ++++++++----
flutter/lib/models/model.dart | 11 +++++++++++
src/client.rs | 18 +++++++++++++++---
4 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart
index b5f876d2e..889ba3fbe 100644
--- a/flutter/lib/common/widgets/peer_card.dart
+++ b/flutter/lib/common/widgets/peer_card.dart
@@ -752,14 +752,13 @@ abstract class BasePeerCard extends StatelessWidget {
style: style,
),
proc: () async {
- if (tab == PeerTabIndex.ab) {
- gFFI.abModel.unrememberPassword(id);
- await bind.mainForgetPassword(id: id);
- gFFI.abModel.pushAb();
- } else {
- bind.mainForgetPassword(id: id);
- showToast(translate('Successful'));
+ bool result = gFFI.abModel.changePassword(id, '');
+ await bind.mainForgetPassword(id: id);
+ if (result) {
+ bool toast = tab == PeerTabIndex.ab;
+ gFFI.abModel.pushAb(toastIfFail: toast, toastIfSucc: toast);
}
+ showToast(translate('Successful'));
},
padding: menuPadding,
dismissOnClicked: true,
diff --git a/flutter/lib/models/ab_model.dart b/flutter/lib/models/ab_model.dart
index 03e08434f..f5e217472 100644
--- a/flutter/lib/models/ab_model.dart
+++ b/flutter/lib/models/ab_model.dart
@@ -211,12 +211,15 @@ class AbModel {
it.first.alias = alias;
}
- void unrememberPassword(String id) {
+ bool changePassword(String id, String hash) {
final it = peers.where((element) => element.id == id);
- if (it.isEmpty) {
- return;
+ if (it.isNotEmpty) {
+ if (it.first.hash != hash) {
+ it.first.hash = hash;
+ return true;
+ }
}
- it.first.hash = '';
+ return false;
}
Future pushAb(
@@ -225,6 +228,7 @@ class AbModel {
bool isRetry = false}) async {
debugPrint(
"pushAb: toastIfFail:$toastIfFail, toastIfSucc:$toastIfSucc, isRetry:$isRetry");
+ if (!gFFI.userModel.isLogin) return false;
pushError.value = '';
if (isRetry) retrying.value = true;
DateTime startTime = DateTime.now();
diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart
index 4dc17f9c2..6f68524f4 100644
--- a/flutter/lib/models/model.dart
+++ b/flutter/lib/models/model.dart
@@ -241,6 +241,17 @@ class FfiModel with ChangeNotifier {
handleReloading(evt);
} else if (name == 'plugin_option') {
handleOption(evt);
+ } else if (name == "sync_peer_password_to_ab") {
+ if (desktopType == DesktopType.main) {
+ final id = evt['id'];
+ final password = evt['password'];
+ if (id != null && password != null) {
+ if (gFFI.abModel
+ .changePassword(id.toString(), password.toString())) {
+ gFFI.abModel.pushAb(toastIfFail: false, toastIfSucc: false);
+ }
+ }
+ }
} else {
debugPrint('Unknown event name: $name');
}
diff --git a/src/client.rs b/src/client.rs
index 7b4d052aa..3ac6e8bb6 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -1074,7 +1074,7 @@ pub struct LoginConfigHandler {
pub direct: Option,
pub received: bool,
switch_uuid: Option,
- pub save_ab_password_to_recent: bool,
+ pub save_ab_password_to_recent: bool, // true: connected with ab password
}
impl Deref for LoginConfigHandler {
@@ -1656,6 +1656,18 @@ impl LoginConfigHandler {
log::debug!("remove password of {}", self.id);
}
}
+ #[cfg(feature = "flutter")]
+ {
+ // sync ab password with PeerConfig password
+ let password = base64::encode(config.password.clone(), base64::Variant::Original);
+ let evt: HashMap<&str, String> = HashMap::from([
+ ("name", "sync_peer_password_to_ab".to_string()),
+ ("id", self.id.clone()),
+ ("password", password),
+ ]);
+ let evt = serde_json::ser::to_string(&evt).unwrap_or("".to_owned());
+ crate::flutter::push_global_event(crate::flutter::APP_TYPE_MAIN, evt);
+ }
if config.keyboard_mode.is_empty() {
if is_keyboard_mode_supported(&KeyboardMode::Map, get_version_number(&pi.version)) {
config.keyboard_mode = KeyboardMode::Map.to_string();
@@ -2260,12 +2272,12 @@ pub async fn handle_hash(
if !hash.is_empty() {
password = hash;
lc.write().unwrap().save_ab_password_to_recent = true;
- lc.write().unwrap().password = password.clone();
}
}
}
}
}
+ lc.write().unwrap().password = password.clone();
let password = if password.is_empty() {
// login without password, the remote side can click accept
interface.msgbox("input-password", "Password Required", "", "");
@@ -2337,9 +2349,9 @@ pub async fn handle_login_from_ui(
hasher.update(&lc.read().unwrap().hash.salt);
let res = hasher.finalize();
lc.write().unwrap().remember = remember;
- lc.write().unwrap().password = res[..].into();
res[..].into()
};
+ lc.write().unwrap().password = hash_password.clone();
let mut hasher2 = Sha256::new();
hasher2.update(&hash_password[..]);
hasher2.update(&lc.read().unwrap().hash.challenge);
From f8a6423bf4fcbb820694d5a81bea8a9604395703 Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Mon, 21 Aug 2023 11:14:33 +0800
Subject: [PATCH 27/75] interesting, armv6 build very well on oracle arm64
---
.github/workflows/flutter-build.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml
index b0382b38b..3ccf4988a 100644
--- a/.github/workflows/flutter-build.yml
+++ b/.github/workflows/flutter-build.yml
@@ -766,7 +766,7 @@ jobs:
if: ${{ inputs.upload-artifact }}
needs: [generate-bridge-linux, build-vcpkg-deps-linux]
name: build-rust-lib ${{ matrix.job.target }} (${{ matrix.job.os }}) [${{ matrix.job.extra-build-features }}]
- runs-on: [self-hosted, Linux, X64]
+ runs-on: [self-hosted, Linux, ARM64]
strategy:
fail-fast: false
matrix:
@@ -898,7 +898,7 @@ jobs:
export DEFAULT_FEAT=linux_headless
fi
export CARGO_INCREMENTAL=0
- cargo build --jobs 1 --lib --features flutter,flutter_texture_render,${{ matrix.job.extra-build-features }},$DEFAULT_FEAT --release
+ cargo build --lib --features flutter,flutter_texture_render,${{ matrix.job.extra-build-features }},$DEFAULT_FEAT --release
- name: Upload Artifacts
uses: actions/upload-artifact@master
@@ -1015,7 +1015,7 @@ jobs:
if ${{ matrix.job.enable-headless }}; then
export DEFAULT_FEAT=linux_headless
fi
- cargo build --jobs 1 --features inline,${{ matrix.job.extra-build-features }},$DEFAULT_FEAT --release --bins
+ cargo build --features inline,${{ matrix.job.extra-build-features }},$DEFAULT_FEAT --release --bins
# package
mkdir -p ./Release
mv ./target/release/rustdesk ./Release/rustdesk
From e03399749a39f92a1c6f300fe66297aa8e23e273 Mon Sep 17 00:00:00 2001
From: Ibnul Mutaki
Date: Mon, 21 Aug 2023 16:10:55 +0700
Subject: [PATCH 28/75] add and fixing some translate Indonesia
---
src/lang/id.rs | 478 ++++++++++++++++++++++++-------------------------
1 file changed, 239 insertions(+), 239 deletions(-)
diff --git a/src/lang/id.rs b/src/lang/id.rs
index 4692b280b..45cb3f1c8 100644
--- a/src/lang/id.rs
+++ b/src/lang/id.rs
@@ -4,7 +4,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Status", "Status"),
("Your Desktop", "Desktop Anda"),
("desk_tip", "Desktop Anda dapat diakses dengan ID dan kata sandi ini."),
- ("Password", "Password"),
+ ("Password", "Kata sandi"),
("Ready", "Siap"),
("Established", "Didirikan"),
("connecting_status", "Menghubungkan ke jaringan RustDesk..."),
@@ -15,48 +15,48 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("not_ready_status", "Belum siap. Silakan periksa koneksi Anda"),
("Control Remote Desktop", "Kontrol Remote Desktop"),
("Transfer File", "File Transfer"),
- ("Connect", "Terhubung"),
+ ("Connect", "Hubungkan"),
("Recent Sessions", "Sesi Terkini"),
("Address Book", "Buku Alamat"),
("Confirmation", "Konfirmasi"),
("TCP Tunneling", "TCP Tunneling"),
("Remove", "Hapus"),
- ("Refresh random password", "Segarkan kata sandi acak"),
- ("Set your own password", "Tetapkan kata sandi Anda sendiri"),
+ ("Refresh random password", "Perbarui kata sandi acak"),
+ ("Set your own password", "Tetapkan kata sandi Anda"),
("Enable Keyboard/Mouse", "Aktifkan Keyboard/Mouse"),
("Enable Clipboard", "Aktifkan Papan Klip"),
("Enable File Transfer", "Aktifkan Transfer File"),
("Enable TCP Tunneling", "Aktifkan TCP Tunneling"),
- ("IP Whitelisting", "Daftar Putih IP"),
+ ("IP Whitelisting", "Daftar IP yang diizinkan"),
("ID/Relay Server", "ID/Relay Server"),
("Import Server Config", "Impor Konfigurasi Server"),
- ("Export Server Config", "Ekspor Konfigutasi Server"),
+ ("Export Server Config", "Ekspor Konfigurasi Server"),
("Import server configuration successfully", "Impor konfigurasi server berhasil"),
("Export server configuration successfully", "Ekspor konfigurasi server berhasil"),
("Invalid server configuration", "Konfigurasi server tidak valid"),
("Clipboard is empty", "Papan klip kosong"),
("Stop service", "Hentikan Layanan"),
("Change ID", "Ubah ID"),
- ("Your new ID", ""),
- ("length %min% to %max%", ""),
- ("starts with a letter", ""),
- ("allowed characters", ""),
+ ("Your new ID", "ID baru anda"),
+ ("length %min% to %max%", "panjang %min% s/d %max%"),
+ ("starts with a letter", "Dimulai dengan huruf"),
+ ("allowed characters", "Karakter yang dapat digunakan"),
("id_change_tip", "Hanya karakter a-z, A-Z, 0-9 dan _ (underscore) yang diperbolehkan. Huruf pertama harus a-z, A-Z. Panjang antara 6 dan 16."),
- ("Website", "Website"),
+ ("Website", "Situs Web"),
("About", "Tentang"),
- ("Slogan_tip", ""),
+ ("Slogan_tip", "Dibuat dengan penuh kasih sayang dalam dunia yang penuh kekacauan ini"),
("Privacy Statement", "Pernyataan Privasi"),
("Mute", "Bisukan"),
("Build Date", ""),
- ("Version", ""),
+ ("Version", "Versi"),
("Home", ""),
- ("Audio Input", "Masukkan Audio"),
+ ("Audio Input", "Input Audio"),
("Enhancements", "Peningkatan"),
("Hardware Codec", "Codec Perangkat Keras"),
("Adaptive bitrate", "Kecepatan Bitrate Adaptif"),
("ID Server", "Server ID"),
("Relay Server", "Server Relay"),
- ("API Server", "API Server"),
+ ("API Server", "Server API"),
("invalid_http", "harus dimulai dengan http:// atau https://"),
("Invalid IP", "IP tidak valid"),
("Invalid format", "Format tidak valid"),
@@ -66,16 +66,16 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Cancel", "Batal"),
("Skip", "Lanjutkan"),
("Close", "Tutup"),
- ("Retry", "Ulangi"),
+ ("Retry", "Coba lagi"),
("OK", "Oke"),
("Password Required", "Kata sandi dibutuhkan"),
("Please enter your password", "Silahkan masukkan kata sandi anda"),
- ("Remember password", "Ingat Password"),
+ ("Remember password", "Ingat kata sandi"),
("Wrong Password", "Kata sandi Salah"),
("Do you want to enter again?", "Apakah anda ingin masuk lagi?"),
("Connection Error", "Kesalahan koneksi"),
("Error", "Kesalahan"),
- ("Reset by the peer", "Setel ulang oleh rekan"),
+ ("Reset by the peer", "Direset oleh rekan"),
("Connecting...", "Menghubungkan..."),
("Connection in progress. Please wait.", "Koneksi sedang berlangsung. Mohon tunggu."),
("Please try 1 minute later", "Silahkan coba 1 menit lagi"),
@@ -114,19 +114,19 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Speed", "Kecepatan"),
("Custom Image Quality", "Sesuaikan Kualitas Gambar"),
("Privacy mode", "Mode Privasi"),
- ("Block user input", "Blokir masukan pengguna"),
- ("Unblock user input", "Jangan blokir masukan pengguna"),
+ ("Block user input", "Blokir input pengguna"),
+ ("Unblock user input", "Jangan blokir input pengguna"),
("Adjust Window", "Sesuaikan Jendela"),
("Original", "Asli"),
("Shrink", "Susutkan"),
("Stretch", "Regangkan"),
- ("Scrollbar", "Scroll bar"),
- ("ScrollAuto", "Gulir Otomatis"),
+ ("Scrollbar", "Scrollbar"),
+ ("ScrollAuto", "Scroll Otomatis"),
("Good image quality", "Kualitas Gambar Baik"),
("Balanced", "Seimbang"),
("Optimize reaction time", "Optimalkan waktu reaksi"),
("Custom", "Kustom"),
- ("Show remote cursor", "Tampilkan remote kursor"),
+ ("Show remote cursor", "Tampilkan kursor remote"),
("Show quality monitor", "Tampilkan kualitas monitor"),
("Disable clipboard", "Matikan papan klip"),
("Lock after session end", "Kunci setelah sesi berakhir"),
@@ -143,30 +143,30 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Failed to connect via rendezvous server", "Gagal terkoneksi via rendezvous server"),
("Failed to connect via relay server", "Gagal terkoneksi via relay server"),
("Failed to make direct connection to remote desktop", "Gagal membuat koneksi langsung ke desktop jarak jauh"),
- ("Set Password", "Tetapkan Password"),
+ ("Set Password", "Tetapkan kata sandi"),
("OS Password", "Kata Sandi OS"),
("install_tip", "Karena UAC, RustDesk tidak dapat bekerja dengan baik sebagai sisi remote dalam beberapa kasus. Untuk menghindari UAC, silakan klik tombol di bawah ini untuk menginstal RustDesk ke sistem."),
("Click to upgrade", "Klik untuk upgrade"),
- ("Click to download", "Kli untuk download"),
- ("Click to update", "Klik untuk update"),
+ ("Click to download", "Klik untuk unduh"),
+ ("Click to update", "Klik untuk memperbarui"),
("Configure", "Konfigurasi"),
("config_acc", "Untuk mengontrol Desktop Anda dari jarak jauh, Anda perlu memberikan izin \"Aksesibilitas\" RustDesk."),
("config_screen", "Untuk mengakses Desktop Anda dari jarak jauh, Anda perlu memberikan izin \"Perekaman Layar\" RustDesk."),
("Installing ...", "Menginstall"),
("Install", "Instal"),
("Installation", "Instalasi"),
- ("Installation Path", "Jalur Instalasi"),
+ ("Installation Path", "Direktori Instalasi"),
("Create start menu shortcuts", "Buat pintasan start menu"),
("Create desktop icon", "Buat icon desktop"),
("agreement_tip", "Dengan memulai instalasi, Anda menerima perjanjian lisensi."),
("Accept and Install", "Terima dan Install"),
- ("End-user license agreement", "Perjanjian lisensi pengguna akhir"),
- ("Generating ...", "Menghasilkan..."),
+ ("End-user license agreement", "Perjanjian lisensi pengguna"),
+ ("Generating ...", "Memproses..."),
("Your installation is lower version.", "Instalasi Anda adalah versi yang lebih rendah."),
("not_close_tcp_tip", "Jangan tutup jendela ini saat menggunakan tunnel"),
- ("Listening ...", "Mendengarkan..."),
- ("Remote Host", "Remote Host"),
- ("Remote Port", "Remote Port"),
+ ("Listening ...", "Menghubungkan..."),
+ ("Remote Host", "Host Remote"),
+ ("Remote Port", "Port Remote"),
("Action", "Aksi"),
("Add", "Tambah"),
("Local Port", "Port Lokal"),
@@ -182,46 +182,46 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Allow using keyboard and mouse", "Izinkan menggunakan keyboard dan mouse"),
("Allow using clipboard", "Izinkan menggunakan papan klip"),
("Allow hearing sound", "Izinkan mendengarkan suara"),
- ("Allow file copy and paste", "Izinkan penyalinan dan tempel file"),
- ("Connected", "Terkoneksi"),
+ ("Allow file copy and paste", "Izinkan salin dan tempel file"),
+ ("Connected", "Terhubung"),
("Direct and encrypted connection", "Koneksi langsung dan terenkripsi"),
- ("Relayed and encrypted connection", "Koneksi relai dan terenkripsi"),
+ ("Relayed and encrypted connection", "Koneksi relay dan terenkripsi"),
("Direct and unencrypted connection", "Koneksi langsung dan tidak terenkripsi"),
- ("Relayed and unencrypted connection", "Koneksi relai dan tidak terenkripsi"),
- ("Enter Remote ID", "Masukkan Remote ID"),
- ("Enter your password", "Masukkan password anda"),
+ ("Relayed and unencrypted connection", "Koneksi relay dan tidak terenkripsi"),
+ ("Enter Remote ID", "Masukkan ID Remote"),
+ ("Enter your password", "Masukkan kata sandi anda"),
("Logging in...", "Masuk..."),
("Enable RDP session sharing", "Aktifkan berbagi sesi RDP"),
- ("Auto Login", "Auto Login (Hanya valid jika Anda menyetel \"Kunci setelah sesi berakhir\")"),
+ ("Auto Login", "Auto Login (Hanya berlaku jika Anda mengatur \"Kunci setelah sesi berakhir\")"),
("Enable Direct IP Access", "Aktifkan Akses IP Langsung"),
("Rename", "Ubah nama"),
("Space", "Spasi"),
("Create Desktop Shortcut", "Buat Pintasan Desktop"),
- ("Change Path", "Ubah Jalur"),
+ ("Change Path", "Ubah Direktori"),
("Create Folder", "Buat Folder"),
("Please enter the folder name", "Silahkan masukkan nama folder"),
- ("Fix it", "Memperbaiki"),
+ ("Fix it", "Perbaiki"),
("Warning", "Peringatan"),
("Login screen using Wayland is not supported", "Layar masuk menggunakan Wayland tidak didukung"),
("Reboot required", "Diperlukan boot ulang"),
("Unsupported display server", "Server tampilan tidak didukung "),
- ("x11 expected", "x11 diharapkan"),
+ ("x11 expected", "Diperlukan x11"),
("Port", "Port"),
("Settings", "Pengaturan"),
- ("Username", "Username"),
+ ("Username", "Nama pengguna"),
("Invalid port", "Kesalahan port"),
("Closed manually by the peer", "Ditutup secara manual oleh peer"),
- ("Enable remote configuration modification", "Aktifkan modifikasi konfigurasi jarak jauh"),
+ ("Enable remote configuration modification", "Aktifkan modifikasi konfigurasi remotE"),
("Run without install", "Jalankan tanpa menginstal"),
- ("Connect via relay", ""),
- ("Always connect via relay", "Selalu terhubung melalui relai"),
- ("whitelist_tip", "Hanya whitelisted IP yang dapat mengakses saya"),
+ ("Connect via relay", "Sambungkan via relay"),
+ ("Always connect via relay", "Selalu terhubung melalui relay"),
+ ("whitelist_tip", "Hanya IP yang diizikan dapat mengakses"),
("Login", "Masuk"),
- ("Verify", ""),
- ("Remember me", ""),
- ("Trust this device", ""),
- ("Verification code", ""),
- ("verification_tip", ""),
+ ("Verify", "Verifikasi"),
+ ("Remember me", "Ingatkan saya"),
+ ("Trust this device", "Izinkan perangkat ini"),
+ ("Verification code", "Kode verifikasi"),
+ ("verification_tip", "Kode verifikasi sudah dikirim ke email yang terdaftar, masukkan kode verifikasi untuk melanjutkan."),
("Logout", "Keluar"),
("Tags", "Tag"),
("Search ID", "Cari ID"),
@@ -230,31 +230,31 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Add Tag", "Tambah Tag"),
("Unselect all tags", "Batalkan pilihan semua tag"),
("Network error", "Kesalahan Jaringan"),
- ("Username missed", "Username tidak sesuai"),
+ ("Username missed", "Nama pengguna tidak sesuai"),
("Password missed", "Kata sandi tidak sesuai"),
- ("Wrong credentials", "Username atau password salah"),
- ("The verification code is incorrect or has expired", ""),
+ ("Wrong credentials", "Nama pengguna atau kata sandi salah"),
+ ("The verification code is incorrect or has expired", "Kode verifikasi salah atau sudah kadaluarsa"),
("Edit Tag", "Ubah Tag"),
- ("Unremember Password", "Lupa Kata Sandi"),
+ ("Unremember Password", "Lupakan Kata Sandi"),
("Favorites", "Favorit"),
("Add to Favorites", "Tambah ke Favorit"),
("Remove from Favorites", "Hapus dari favorit"),
("Empty", "Kosong"),
("Invalid folder name", "Nama folder tidak valid"),
- ("Socks5 Proxy", "Socks5 Proxy"),
+ ("Socks5 Proxy", "Proxy Socks5"),
("Hostname", "Hostname"),
("Discovered", "Telah ditemukan"),
("install_daemon_tip", "Untuk memulai saat boot, Anda perlu menginstal system service."),
- ("Remote ID", "Remote ID"),
+ ("Remote ID", "ID Remote"),
("Paste", "Tempel"),
("Paste here?", "Tempel disini?"),
("Are you sure to close the connection?", "Apakah anda yakin akan menutup koneksi?"),
- ("Download new version", "Untuk versi baru"),
- ("Touch mode", "Mode Sentuh"),
+ ("Download new version", "Unduh versi baru"),
+ ("Touch mode", "Mode Layar Sentuh"),
("Mouse mode", "Mode Mouse"),
("One-Finger Tap", "Ketuk Satu Jari"),
("Left Mouse", "Mouse Kiri"),
- ("One-Long Tap", "Ketuk Satu Panjang"),
+ ("One-Long Tap", "Ketuk Tahan"),
("Two-Finger Tap", "Ketuk Dua Jari"),
("Right Mouse", "Mouse Kanan"),
("One-Finger Move", "Gerakan Satu Jari"),
@@ -275,25 +275,25 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Total", "Total"),
("items", "item"),
("Selected", "Dipilih"),
- ("Screen Capture", "Rekam Layar"),
- ("Input Control", "kontrol input"),
+ ("Screen Capture", "Tangkapan Layar"),
+ ("Input Control", "Kontrol input"),
("Audio Capture", "Rekam Suara"),
("File Connection", "Koneksi File"),
- ("Screen Connection", "koneksi layar"),
- ("Do you accept?", "Apakah diperbolehkan?"),
+ ("Screen Connection", "Koneksi layar"),
+ ("Do you accept?", "Apakah anda setuju?"),
("Open System Setting", "Buka Pengaturan Sistem"),
- ("How to get Android input permission?", ""),
+ ("How to get Android input permission?", "Bagaimana cara mendapatkan izin input dari Android?"),
("android_input_permission_tip1", "Agar perangkat jarak jauh dapat mengontrol perangkat Android Anda melalui mouse atau sentuhan, Anda harus mengizinkan RustDesk untuk menggunakan layanan \"Aksesibilitas\"."),
("android_input_permission_tip2", "Silakan buka halaman pengaturan sistem berikutnya, temukan dan masuk ke [Layanan Terinstal], aktifkan layanan [Input RustDesk]."),
- ("android_new_connection_tip", "Permintaan kontrol baru telah diterima, yang ingin mengontrol perangkat Anda saat ini."),
- ("android_service_will_start_tip", "Mengaktifkan \"Tangkapan Layar\" akan memulai layanan secara otomatis, memungkinkan perangkat lain untuk meminta sambungan ke perangkat Anda."),
- ("android_stop_service_tip", "Menutup layanan akan secara otomatis menutup semua koneksi yang dibuat."),
+ ("android_new_connection_tip", "Permintaan akses remote telah diterima"),
+ ("android_service_will_start_tip", "Mengaktifkan \"Tangkapan Layar\" akan memulai secara otomatis, memungkinkan perangkat lain untuk meminta koneksi ke perangkat Anda."),
+ ("android_stop_service_tip", "Menutup layanan secara otomatis akan menutup semua koneksi yang dibuat."),
("android_version_audio_tip", "Versi Android saat ini tidak mendukung pengambilan audio, harap tingkatkan ke Android 10 atau lebih tinggi."),
- ("android_start_service_tip", ""),
- ("android_permission_may_not_change_tip", ""),
+ ("android_start_service_tip", "Tap [Mulai Layanan] atau aktifkan izin [Tangkapan Layar] untuk memulai berbagi layar."),
+ ("android_permission_may_not_change_tip", "Izin untuk koneksi yang sudah terhubung mungkin tidak dapat diubah secara instan hingga terhubung kembali"),
("Account", "Akun"),
- ("Overwrite", "Timpa"),
- ("This file exists, skip or overwrite this file?", "File ini sudah ada, lewati atau timpa file ini?"),
+ ("Overwrite", "Ganti"),
+ ("This file exists, skip or overwrite this file?", "File ini sudah ada, lewati atau ganti file ini?"),
("Quit", "Keluar"),
("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"),
("Help", "Bantuan"),
@@ -303,30 +303,30 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Unsupported", "Tidak didukung"),
("Peer denied", "Rekan ditolak"),
("Please install plugins", "Silakan instal plugin"),
- ("Peer exit", "keluar rekan"),
+ ("Peer exit", "Rekan keluar"),
("Failed to turn off", "Gagal mematikan"),
- ("Turned off", "Matikan"),
+ ("Turned off", "Dimatikan"),
("In privacy mode", "Dalam mode privasi"),
("Out privacy mode", "Keluar dari mode privasi"),
("Language", "Bahasa"),
- ("Keep RustDesk background service", "Pertahankan RustDesk berjalan pada background service"),
+ ("Keep RustDesk background service", "Pertahankan RustDesk berjalan pada service background"),
("Ignore Battery Optimizations", "Abaikan Pengoptimalan Baterai"),
- ("android_open_battery_optimizations_tip", ""),
- ("Start on Boot", ""),
- ("Start the screen sharing service on boot, requires special permissions", ""),
- ("Connection not allowed", "Koneksi tidak dijinkan"),
- ("Legacy mode", "Mode lama"),
+ ("android_open_battery_optimizations_tip", "Jika kamu ingin menonaktifkan fitur ini, buka halam pengaturan, cari dan pilih [Baterai], Uncheck [Tidak dibatasi]"),
+ ("Start on Boot", "Mulai saat dihidupkan"),
+ ("Start the screen sharing service on boot, requires special permissions", "Mulai layanan berbagi layar saat sistem dinyalakan, memerlukan izin khusus."),
+ ("Connection not allowed", "Koneksi tidak dizinkan"),
+ ("Legacy mode", "Mode lawas"),
("Map mode", "Mode peta"),
("Translate mode", "Mode terjemahan"),
("Use permanent password", "Gunakan kata sandi permanaen"),
- ("Use both passwords", "Gunakan kedua kata sandi "),
+ ("Use both passwords", "Gunakan kedua kata sandi"),
("Set permanent password", "Setel kata sandi permanen"),
- ("Enable Remote Restart", "Aktifkan Restart Jarak Jauh"),
- ("Allow remote restart", "Ijinkan Restart Jarak Jauh"),
- ("Restart Remote Device", "Restart Perangkat Jarak Jauh"),
- ("Are you sure you want to restart", "Apakah Anda yakin untuk memulai ulang"),
- ("Restarting Remote Device", "Memulai Ulang Perangkat Jarak Jauh"),
- ("remote_restarting_tip", ""),
+ ("Enable Remote Restart", "Aktifkan Restart Remote"),
+ ("Allow remote restart", "Ijinkan Restart Remote"),
+ ("Restart Remote Device", "Restart Perangkat Remote"),
+ ("Are you sure you want to restart", "Apakah Anda yakin ingin merestart"),
+ ("Restarting Remote Device", "Merestart Perangkat Remote"),
+ ("remote_restarting_tip", "Perangkat remote sedang merestart, harap tutup pesan ini dan sambungkan kembali dengan kata sandi permanen setelah beberapa saat."),
("Copied", "Disalin"),
("Exit Fullscreen", "Keluar dari Layar Penuh"),
("Fullscreen", "Layar penuh"),
@@ -334,11 +334,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Select Monitor", "Pilih Monitor"),
("Control Actions", "Tindakan Kontrol"),
("Display Settings", "Pengaturan tampilan"),
- ("Ratio", "Perbandingan"),
+ ("Ratio", "Rasio"),
("Image Quality", "Kualitas gambar"),
- ("Scroll Style", "Gaya Gulir"),
- ("Show Toolbar", ""),
- ("Hide Toolbar", ""),
+ ("Scroll Style", "Gaya Scroll"),
+ ("Show Toolbar", "Tampilkan Toolbar"),
+ ("Hide Toolbar", "Sembunyikan Toolbar"),
("Direct Connection", "Koneksi langsung"),
("Relay Connection", "Koneksi Relay"),
("Secure Connection", "Koneksi aman"),
@@ -348,31 +348,31 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("General", "Umum"),
("Security", "Keamanan"),
("Theme", "Tema"),
- ("Dark Theme", "Tema gelap"),
- ("Light Theme", ""),
+ ("Dark Theme", "Tema Gelap"),
+ ("Light Theme", "Tema Terang"),
("Dark", "Gelap"),
("Light", "Terang"),
- ("Follow System", "Ikuti sistem"),
+ ("Follow System", "Ikuti Sistem"),
("Enable hardware codec", "Aktifkan codec perangkat keras"),
- ("Unlock Security Settings", "Buka Kunci Pengaturan Keamanan"),
+ ("Unlock Security Settings", "Buka Keamanan Pengaturan"),
("Enable Audio", "Aktifkan Audio"),
- ("Unlock Network Settings", "Buka Kunci Pengaturan Jaringan"),
+ ("Unlock Network Settings", "Buka Keamanan Pengaturan Jaringan"),
("Server", "Server"),
- ("Direct IP Access", "Direct IP Access"),
+ ("Direct IP Access", "Akses IP Langsung"),
("Proxy", "Proxy"),
("Apply", "Terapkan"),
("Disconnect all devices?", "Putuskan sambungan semua perangkat?"),
- ("Clear", ""),
- ("Audio Input Device", ""),
- ("Use IP Whitelisting", "Gunakan Daftar Putih IP"),
+ ("Clear", "Bersihkan"),
+ ("Audio Input Device", "Input Perangkat Audio"),
+ ("Use IP Whitelisting", "Gunakan daftar IP yang diizinkan"),
("Network", "Jaringan"),
("Enable RDP", "Aktifkan RDP"),
- ("Pin Toolbar", ""),
- ("Unpin Toolbar", ""),
- ("Recording", "Rekaman"),
+ ("Pin Toolbar", "Sematkan Toolbar"),
+ ("Unpin Toolbar", "Batal sematkan Toolbar"),
+ ("Recording", "Sedang Merekam"),
("Directory", "Direktori"),
("Automatically record incoming sessions", "Secara otomatis merekam sesi masuk"),
- ("Change", "Mengubah"),
+ ("Change", "Ubah"),
("Start session recording", "Mulai sesi perekaman"),
("Stop session recording", "Hentikan sesi perekaman"),
("Enable Recording Session", "Aktifkan Sesi Perekaman"),
@@ -381,8 +381,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Deny LAN Discovery", "Tolak Penemuan LAN"),
("Write a message", "Menulis pesan"),
("Prompt", ""),
- ("Please wait for confirmation of UAC...", ""),
- ("elevated_foreground_window_tip", ""),
+ ("Please wait for confirmation of UAC...", "Harap tunggu konfirmasi UAC"),
+ ("elevated_foreground_window_tip", "Jendela remote desktop ini memerlukan hak akses khusus, jadi anda tidak bisa menggunakan mouse dan keyboard untuk sementara. Kamu bisa meminta pengguna remote untuk menyembunyikan jendela ini atau klik tombol elevasi di jendela pengaturan koneksi. Untuk menghindari masalah ini, direkomendasikan untuk menginstall aplikasi secara permanen"),
("Disconnected", "Terputus"),
("Other", "Lainnya"),
("Confirm before closing multiple tabs", "Konfirmasi sebelum menutup banyak tab"),
@@ -391,152 +391,152 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Screen Share", "Berbagi Layar"),
("Wayland requires Ubuntu 21.04 or higher version.", "Wayland membutuhkan Ubuntu 21.04 atau versi yang lebih tinggi."),
("Wayland requires higher version of linux distro. Please try X11 desktop or change your OS.", "Wayland membutuhkan versi distro linux yang lebih tinggi. Silakan coba desktop X11 atau ubah OS Anda."),
- ("JumpLink", "View"),
- ("Please Select the screen to be shared(Operate on the peer side).", "Silakan Pilih layar yang akan dibagikan (Operasi di sisi rekan)."),
+ ("JumpLink", "Tautan Cepat"),
+ ("Please Select the screen to be shared(Operate on the peer side).", "Silakan Pilih layar yang akan dibagikan kepada rekan."),
("Show RustDesk", "Tampilkan RustDesk"),
("This PC", "PC ini"),
("or", "atau"),
("Continue with", "Lanjutkan dengan"),
- ("Elevate", ""),
- ("Zoom cursor", ""),
+ ("Elevate", "Elevasi"),
+ ("Zoom cursor", "Perbersar Kursor"),
("Accept sessions via password", "Izinkan sesi dengan kata sandi"),
("Accept sessions via click", "Izinkan sesi dengan klik"),
("Accept sessions via both", "Izinkan sesi dengan keduanya"),
- ("Please wait for the remote side to accept your session request...", "Harap tunggu sisi jarak jauh untuk menerima permintaan sesi Anda..."),
+ ("Please wait for the remote side to accept your session request...", "Harap tunggu pihak pengguna remote untuk menerima permintaan sesi..."),
("One-time Password", "Kata sandi satu kali"),
("Use one-time password", "Gunakan kata sandi satu kali"),
- ("One-time password length", ""),
- ("Request access to your device", ""),
- ("Hide connection management window", ""),
- ("hide_cm_tip", ""),
- ("wayland_experiment_tip", ""),
- ("Right click to select tabs", ""),
- ("Skipped", ""),
- ("Add to Address Book", ""),
- ("Group", ""),
+ ("One-time password length", "Panjang kata sandi satu kali pakai"),
+ ("Request access to your device", "Permintaan akses ke perangkat ini"),
+ ("Hide connection management window", "Sembunyikan jendela pengaturan koneksi"),
+ ("hide_cm_tip", "Izinkan untuk menyembunyikan hanya jika menerima sesi melalui kata sandi dan menggunakan kata sandi permanen"),
+ ("wayland_experiment_tip", "Dukungan Wayland masih dalam tahap percobaan, harap gunakan X11 jika Anda memerlukan akses tanpa pengawasan"),
+ ("Right click to select tabs", "Klik kanan untuk memilih tab"),
+ ("Skipped", "Dilewati"),
+ ("Add to Address Book", "Tambahkan ke Buku Alamat"),
+ ("Group", "Grup"),
("Search", "Pencarian"),
- ("Closed manually by web console", ""),
- ("Local keyboard type", ""),
- ("Select local keyboard type", ""),
- ("software_render_tip", ""),
- ("Always use software rendering", ""),
- ("config_input", ""),
- ("config_microphone", ""),
- ("request_elevation_tip", ""),
- ("Wait", ""),
- ("Elevation Error", ""),
- ("Ask the remote user for authentication", ""),
- ("Choose this if the remote account is administrator", ""),
- ("Transmit the username and password of administrator", ""),
- ("still_click_uac_tip", ""),
- ("Request Elevation", ""),
- ("wait_accept_uac_tip", ""),
- ("Elevate successfully", ""),
- ("uppercase", ""),
- ("lowercase", ""),
- ("digit", ""),
- ("special character", ""),
- ("length>=8", ""),
- ("Weak", ""),
- ("Medium", ""),
- ("Strong", ""),
- ("Switch Sides", ""),
- ("Please confirm if you want to share your desktop?", ""),
- ("Display", ""),
- ("Default View Style", ""),
- ("Default Scroll Style", ""),
- ("Default Image Quality", ""),
- ("Default Codec", ""),
- ("Bitrate", ""),
- ("FPS", ""),
- ("Auto", ""),
- ("Other Default Options", ""),
- ("Voice call", ""),
- ("Text chat", ""),
- ("Stop voice call", ""),
- ("relay_hint_tip", ""),
- ("Reconnect", ""),
- ("Codec", ""),
- ("Resolution", ""),
- ("No transfers in progress", ""),
- ("Set one-time password length", ""),
- ("install_cert_tip", ""),
- ("confirm_install_cert_tip", ""),
- ("RDP Settings", ""),
- ("Sort by", ""),
- ("New Connection", ""),
- ("Restore", ""),
- ("Minimize", ""),
- ("Maximize", ""),
- ("Your Device", ""),
- ("empty_recent_tip", ""),
- ("empty_favorite_tip", ""),
- ("empty_lan_tip", ""),
- ("empty_address_book_tip", ""),
+ ("Closed manually by web console", "Ditutup secara manual dari konsol web."),
+ ("Local keyboard type", "Tipe papan ketik"),
+ ("Select local keyboard type", "Pilih tipe papan ketik"),
+ ("software_render_tip", "Jika kamu menggunakan kartu grafis Nvidia pada sistem linux dan jendela windows ditutup secara instan setelah terhung, silahkan ubah ke driver open-source Nouveau, dibutukan untuk merestart aplikasi"),
+ ("Always use software rendering", "Selalu gunakan software rendering"),
+ ("config_input", "Untuk menggunakan input keyboard remote, anda perlu memberikan izin \"Pemantauan Input\" pada RustDesk"),
+ ("config_microphone", "Untuk berbicara secara remote, anda perlu memberikan izin \"Rekam Audio\" pada RustDesk"),
+ ("request_elevation_tip", "Anda juga bisa meminta izin elevasi jika ada pihak pengguna remote"),
+ ("Wait", "Tunggu"),
+ ("Elevation Error", "Kesalahan Elevasi"),
+ ("Ask the remote user for authentication", "Minta pihak pengguna remote untuk otentikasi"),
+ ("Choose this if the remote account is administrator", "Pilih ini jika akun adalah \"administrator\""),
+ ("Transmit the username and password of administrator", "Transmisikan nama pengguna dan kata sandi administrator"),
+ ("still_click_uac_tip", "Masih memerlukan persetujuan pihak pengguna remote untuk mengklik OK pada jendela UAC RustDesk yang sedang berjalan"),
+ ("Request Elevation", "Permintaan Elevasi"),
+ ("wait_accept_uac_tip", "Harap tunggu pihak pengguna remote menerima jendela UAC."),
+ ("Elevate successfully", "Elevasi berhasil"),
+ ("uppercase", "Huruf besar"),
+ ("lowercase", "Huruf kecil"),
+ ("digit", "angka"),
+ ("special character", "Karakter spesial"),
+ ("length>=8", "panjang>=8"),
+ ("Weak", "Lemah"),
+ ("Medium", "Sedang"),
+ ("Strong", "Kuat"),
+ ("Switch Sides", "Tukar Posisi"),
+ ("Please confirm if you want to share your desktop?", "Harap konfirmasi apakah Anda ingin berbagi layar?"),
+ ("Display", "Tampilan"),
+ ("Default View Style", "Gaya Tampilan Default"),
+ ("Default Scroll Style", "Gaya Scroll Default"),
+ ("Default Image Quality", "Kualitas Gambar Default"),
+ ("Default Codec", "Codec default"),
+ ("Bitrate", "Bitrate"),
+ ("FPS", "FPS"),
+ ("Auto", "Otomatis"),
+ ("Other Default Options", "Opsi Default Lainnya"),
+ ("Voice call", "Panggilan suara"),
+ ("Text chat", "Obrolan Teks"),
+ ("Stop voice call", "Hentikan panggilan suara"),
+ ("relay_hint_tip", "Tidak memungkinkan untuk terhubung secara langsung; anda bisa mencoba terhubung via relay. Selain itu, jika ingin menggunakan relay pada percobaan pertama, silahkan tambah akhiran \"/r\" pada ID atau pilih \"Selalu terhubung via relay\" di pilihan sesi terbaru."),
+ ("Reconnect", "Menyambungkan ulang"),
+ ("Codec", "Codec"),
+ ("Resolution", "Resolusi"),
+ ("No transfers in progress", "Tidak ada transfer data yang sedang berlangsung"),
+ ("Set one-time password length", "Atur panjang kata sandi satu kali pakai"),
+ ("install_cert_tip", "Install sertifikat RustDesk"),
+ ("confirm_install_cert_tip", "Ini adalah sertifikat pengujian RustDesk, yang dapat dipercaya. Sertifikat ini akan digunakan untuk menginstal driver RustDesk saat diperlukan"),
+ ("RDP Settings", "Pengaturan RDP"),
+ ("Sort by", "Urutkan berdasarkan"),
+ ("New Connection", "Koneksi baru"),
+ ("Restore", "Mengembalikan"),
+ ("Minimize", "Meminimalkan"),
+ ("Maximize", "Memaksimalkan"),
+ ("Your Device", "Perangkat anda"),
+ ("empty_recent_tip", "Tidak ada sesi terbaru!"),
+ ("empty_favorite_tip", "Belum ada rekan (peer) favorit?\nTemukan seseorang untuk terhubung dan tambahkan ke favorit!"),
+ ("empty_lan_tip", "Sepertinya kami belum menemukan rekan (peer)"),
+ ("empty_address_book_tip", "Tampaknya saat ini tidak ada rekan yang terdaftar dalam buku alamat Anda"),
("eg: admin", ""),
- ("Empty Username", ""),
- ("Empty Password", ""),
- ("Me", ""),
- ("identical_file_tip", ""),
- ("show_monitors_tip", ""),
- ("View Mode", ""),
- ("login_linux_tip", ""),
- ("verify_rustdesk_password_tip", ""),
- ("remember_account_tip", ""),
- ("os_account_desk_tip", ""),
- ("OS Account", ""),
- ("another_user_login_title_tip", ""),
- ("another_user_login_text_tip", ""),
- ("xorg_not_found_title_tip", ""),
- ("xorg_not_found_text_tip", ""),
- ("no_desktop_title_tip", ""),
- ("no_desktop_text_tip", ""),
- ("No need to elevate", ""),
- ("System Sound", ""),
- ("Default", ""),
- ("New RDP", ""),
+ ("Empty Username", "Nama pengguna kosong"),
+ ("Empty Password", "Kata sandi kosong"),
+ ("Me", "Saya"),
+ ("identical_file_tip", "Data ini identik dengan milik rekan (peer)"),
+ ("show_monitors_tip", "Tampilkan monitor di toolbar"),
+ ("View Mode", "Mode Tampilan"),
+ ("login_linux_tip", "Anda harus masuk ke akun remote linux untuk mengaktifkan sesi X desktop"),
+ ("verify_rustdesk_password_tip", "Verifikasi Kata Sandi RustDesk"),
+ ("remember_account_tip", "Ingat akun ini"),
+ ("os_account_desk_tip", "Akun ini digunakan untuk masuk ke sistem operasi remote dan mengaktifkan sesi desktop dalam mode tanpa tampilan (headless)"),
+ ("OS Account", "Akun OS"),
+ ("another_user_login_title_tip", "Akun ini sedang digunakan"),
+ ("another_user_login_text_tip", "Putuskan koneksi diperangkat lain"),
+ ("xorg_not_found_title_tip", "Xorg tidak ditemukan"),
+ ("xorg_not_found_text_tip", "Silahkan install Xorg"),
+ ("no_desktop_title_tip", "Desktop tidak tersedia"),
+ ("no_desktop_text_tip", "Silahkan install GNOME Desktop"),
+ ("No need to elevate", "Tidak perlu elevasi"),
+ ("System Sound", "Suara Sistem"),
+ ("Default", "Default"),
+ ("New RDP", "RDP Baru"),
("Fingerprint", ""),
("Copy Fingerprint", ""),
("no fingerprints", ""),
- ("Select a peer", ""),
- ("Select peers", ""),
- ("Plugins", ""),
- ("Uninstall", ""),
- ("Update", ""),
- ("Enable", ""),
- ("Disable", ""),
- ("Options", ""),
- ("resolution_original_tip", ""),
- ("resolution_fit_local_tip", ""),
- ("resolution_custom_tip", ""),
+ ("Select a peer", "Pilih rekan"),
+ ("Select peers", "Pilih rekan-rekan"),
+ ("Plugins", "Plugin"),
+ ("Uninstall", "Hapus instalasi"),
+ ("Update", "Perbarui"),
+ ("Enable", "Aktifkan"),
+ ("Disable", "Nonaktifkan"),
+ ("Options", "Opsi"),
+ ("resolution_original_tip", "Resolusi original"),
+ ("resolution_fit_local_tip", "Sesuaikan resolusi lokal"),
+ ("resolution_custom_tip", "Resolusi kustom"),
("Collapse toolbar", ""),
- ("Accept and Elevate", ""),
- ("accept_and_elevate_btn_tooltip", ""),
- ("clipboard_wait_response_timeout_tip", ""),
- ("Incoming connection", ""),
- ("Outgoing connection", ""),
- ("Exit", ""),
- ("Open", ""),
- ("logout_tip", ""),
- ("Service", ""),
- ("Start", ""),
- ("Stop", ""),
- ("exceed_max_devices", ""),
- ("Sync with recent sessions", ""),
- ("Sort tags", ""),
- ("Open connection in new tab", ""),
- ("Move tab to new window", ""),
- ("Can not be empty", ""),
- ("Already exists", ""),
- ("Change Password", ""),
- ("Refresh Password", ""),
- ("ID", ""),
- ("Grid View", ""),
- ("List View", ""),
- ("Select", ""),
- ("Toggle Tags", ""),
- ("pull_ab_failed_tip", ""),
- ("push_ab_failed_tip", ""),
- ("synced_peer_readded_tip", ""),
+ ("Accept and Elevate", "Terima dan Elevasi"),
+ ("accept_and_elevate_btn_tooltip", "Terima koneksi dan elevasi izin UAC"),
+ ("clipboard_wait_response_timeout_tip", "Batas waktu habis saat menunggu respons salinan"),
+ ("Incoming connection", "Koneksi akan masuk"),
+ ("Outgoing connection", "Koneksi akan keluar"),
+ ("Exit", "Keluar"),
+ ("Open", "Buka"),
+ ("logout_tip", "Apakah Anda yakin ingin keluar?"),
+ ("Service", "Service"),
+ ("Start", "Mulai"),
+ ("Stop", "Berhenti"),
+ ("exceed_max_devices", "Anda telah mencapai jumlah maksimal perangkat yang dikelola"),
+ ("Sync with recent sessions", "Sinkronkan dengan sesi terbaru"),
+ ("Sort tags", "Urutkan tag"),
+ ("Open connection in new tab", "Buka koneksi di tab baru"),
+ ("Move tab to new window", "Pindahkan tabn ke jendela baru"),
+ ("Can not be empty", "Tidak boleh kosong"),
+ ("Already exists", "Sudah ada"),
+ ("Change Password", "Ganti kata sandi"),
+ ("Refresh Password", "Perbarui Kata Sandi"),
+ ("ID", "ID"),
+ ("Grid View", "Tampilan Kotak"),
+ ("List View", "Tampilan Daftar"),
+ ("Select", "Pilih"),
+ ("Toggle Tags", "Toggle Tag"),
+ ("pull_ab_failed_tip", "Gagal memuat ulang buku alamat"),
+ ("push_ab_failed_tip", "Gagal menyinkronkan buku alamat ke server"),
+ ("synced_peer_readded_tip", "Perangkat yang terdaftar dalam sesi-sesi terbaru akan di-sinkronkan kembali ke buku alamat."),
].iter().cloned().collect();
}
From 16da5ccc91e328d72c182dc2bd54a8dd19f2c968 Mon Sep 17 00:00:00 2001
From: Ibnul Mutaki
Date: Mon, 21 Aug 2023 21:20:21 +0700
Subject: [PATCH 29/75] fix some mistake on README-ID
---
docs/README-ID.md | 91 +++++++++++++++++++++++++++++++++--------------
1 file changed, 65 insertions(+), 26 deletions(-)
diff --git a/docs/README-ID.md b/docs/README-ID.md
index e071cf6ee..33dab8445 100644
--- a/docs/README-ID.md
+++ b/docs/README-ID.md
@@ -6,52 +6,64 @@
Structure •
Snapshot
[English ] | [Українська ] | [česky ] | [中文 ] | [Magyar ] | [Español ] | [فارسی ] | [Français ] | [Deutsch ] | [Polski ] | [Suomi ] | [മലയാളം ] | [日本語 ] | [Nederlands ] | [Italiano ] | [Русский ] | [Português (Brasil) ] | [Esperanto ] | [한국어 ] | [العربي ] | [Tiếng Việt ] | [Ελληνικά ]
- Kami membutuhkan bantuan Anda untuk menerjemahkan README ini dan RustDesk UI ke bahasa asli anda
+ Kami membutuhkan bantuan kamu untuk menterjemahkan file README dan RustDesk UI ke Bahasa Indonesia
-Birbincang bersama kami: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
+Mari mengobrol bersama kami: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
-Perangkat lunak desktop jarak jauh lainnya, ditulis dengan Rust. Bekerja begitu saja, tidak memerlukan konfigurasi. Anda memiliki kendali penuh atas data Anda, tanpa khawatir tentang keamanan. Anda dapat menggunakan server rendezvous/relay kami, [konfigurasi server sendiri](https://rustdesk.com/server), or [tulis rendezvous/relay server anda sendiri](https://github.com/rustdesk/rustdesk-server-demo).
+Merupakan perangkat lunak Remote Desktop yang baru, dibangun dengan Rust. kamu bisa langsung menggunakannya tanpa perlu konfigurasi tambahan. Serta ,emiliki kontrol penuh terhadap semua data, tanpa perlu merasa was-was tentang isu keamanan, dan yang lebih menarik adalah memiliki opsi untuk menggunakan server rendezvous/relay milik kami, [konfigurasi server sendiri](https://rustdesk.com/server), atau [tulis rendezvous/relay server anda sendiri](https://github.com/rustdesk/rustdesk-server-demo).
-RustDesk menyambut baik kontribusi dari semua orang. Lihat [`docs/CONTRIBUTING.md`](CONTRIBUTING.md) untuk membantu sebelum memulai.
+RustDesk mengajak semua orang untuk ikut berkontribusi. Lihat [`docs/CONTRIBUTING.md`](CONTRIBUTING.md) untuk melihat panduan.
-[**BINARY DOWNLOAD**](https://github.com/rustdesk/rustdesk/releases)
+[**UNDUH BINARY**](https://github.com/rustdesk/rustdesk/releases)
-## Publik Server Gratis
+## Server Publik Gratis
-Di bawah ini adalah server yang bisa Anda gunakan secara gratis, dapat berubah seiring waktu. Jika Anda tidak dekat dengan salah satu dari ini, jaringan Anda mungkin lambat.
-| Lokasi | Vendor | Spesifikasi |
+Di bawah ini merupakan server gratis yang bisa kamu gunakan, seiring waktu kemungkinan akan terjadi perubahan spesifikasi pada setiap server. Jika lokasi kamu berada jauh dengan salah satu server yang tersedia, kemungkinan koneksi akan terasa lambat ketika melakukan proses remote.
+| Lokasi | Penyedia | Spesifikasi |
| --------- | ------------- | ------------------ |
-| Germany | Hetzner | 2 vCPU / 4GB RAM |
-| Ukraine (Kyiv) | [dc.volia](https://dc.volia.com) | 2 vCPU / 4GB RAM |
+| Jerman | [Hetzner](https://www.hetzner.com) | 2 vCPU / 4GB RAM |
+| Ukraina (Kyiv) | [dc.volia](https://dc.volia.com) | 2 vCPU / 4GB RAM |
-## Dependencies
+## Dev Container
-Versi desktop menggunakan [sciter](https://sciter.com/) untuk GUI, silahkan download sendiri sciter dynamic library.
+[](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/rustdesk/rustdesk)
+
+Apabila kamu sudah menginstall VS Code dan Docker, kamu bisa mengklik badge yang ada diatas untuk memulainya. Dengan mengklik badge tersebut secara otomatis akan menginstal ekstensi pada VS Code, lakukan kloning (clone) source code kedalam container volume, dan aktifkan dev container untuk menggunakannya.
+
+## Dependensi
+
+Pada versi desktop, antarmuka pengguna (GUI) menggunakan [Sciter](https://sciter.com/) atau flutter, tutorial ini hanya berlaku untuk Sciter
+
+Kamu bisa mengunduh Sciter dynamic library disini.
[Windows](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.win/x64/sciter.dll) |
[Linux](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so) |
[MacOS](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.osx/libsciter.dylib)
-## Langkah untuk RAW Build
+## Langkah awal untuk memulai
-- Siapkan env pengembangan Rust dan C++ build env
+- Siapkan env development Rust dan env build C++
-- Install [vcpkg](https://github.com/microsoft/vcpkg), dan arahkan `VCPKG_ROOT` env variable dengan benar
+- Install [vcpkg](https://github.com/microsoft/vcpkg), dan atur variabel env `VCPKG_ROOT` dengan benar
- Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static
- Linux/MacOS: vcpkg install libvpx libyuv opus aom
- jalankan `cargo run`
-## Bagaimana Build di Linux
+## [Build](https://rustdesk.com/docs/en/dev/build/)
+
+## Cara Build di Linux
### Ubuntu 18 (Debian 10)
```sh
-sudo apt install -y g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake
+sudo apt install -y zip g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev \
+ libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake make \
+ libclang-dev ninja-build libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
```
### Fedora 28 (CentOS 8)
@@ -78,7 +90,7 @@ export VCPKG_ROOT=$HOME/vcpkg
vcpkg/vcpkg install libvpx libyuv opus aom
```
-### Perbaiki libvpx (Untuk Fedora)
+### Mengatasi masalah libvpx (Untuk Fedora)
```sh
cd vcpkg/buildtrees/libvpx/src
@@ -104,13 +116,40 @@ mv libsciter-gtk.so target/debug
VCPKG_ROOT=$HOME/vcpkg cargo run
```
-### Ubah Wayland menjadi X11 (Xorg)
+### Mengubah Wayland ke X11 (Xorg)
-RustDesk tidak mendukung Wayland. Cek [ini](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) untuk mengonfigurasi Xorg sebagai sesi GNOME default.
+RustDesk tidak mendukung Wayland. Cek [ini](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) untuk mengonfigurasi Xorg sebagai sesi standar di GNOME.
-## Bagaimana build dengan Docker
+## Kompatibilitas dengan Wayland
-Mulailah dengan mengkloning repositori dan build dengan docker container:
+Sepertinya Wayland tidak memiliki API untuk mengirimkan ketukan tombol ke jendela lain. Maka dari itu, RustDesk menggunakan API dari level yang lebih rendah, lebih tepatnya perangkat `/dev/uinput` (linux kernel level)
+
+Saat Wayland menjadi sisi yang dikendalikan atau sisi yang sedang diremote, kamu harus memulai dengan cara ini
+
+```bash
+# Start uinput service
+$ sudo rustdesk --service
+$ rustdesk
+```
+
+**Harap Diperhatikan**: Saat Perekaman layar menggunakan Wayland antarmuka (UI) yang ditampilkan akan berbeda. Untuk saat ini RustDesk hanya mendukung org.freedesktop.portal.ScreenCast.
+
+```bash
+$ dbus-send --session --print-reply \
+ --dest=org.freedesktop.portal.Desktop \
+ /org/freedesktop/portal/desktop \
+ org.freedesktop.DBus.Properties.Get \
+ string:org.freedesktop.portal.ScreenCast string:version
+# Not support
+Error org.freedesktop.DBus.Error.InvalidArgs: No such interface “org.freedesktop.portal.ScreenCast”
+# Support
+method return time=1662544486.931020 sender=:1.54 -> destination=:1.139 serial=257 reply_serial=2
+ variant uint32 4
+```
+
+## Cara Build dengan Docker
+
+Mulailah dengan melakukan kloning (clone) repositori dan build dengan docker container:
```sh
git clone https://github.com/rustdesk/rustdesk
@@ -118,25 +157,25 @@ cd rustdesk
docker build -t "rustdesk-builder" .
```
-Kemudian, setiap kali Anda perlu build aplikasi, jalankan perintah berikut:
+Selanjutnya, setiap kali ketika kamu akan melakukan build aplikasi, jalankan perintah berikut:
```sh
docker run --rm -it -v $PWD:/home/user/rustdesk -v rustdesk-git-cache:/home/user/.cargo/git -v rustdesk-registry-cache:/home/user/.cargo/registry -e PUID="$(id -u)" -e PGID="$(id -g)" rustdesk-builder
```
-Perhatikan bahwa build pertama mungkin memerlukan waktu lebih lama sebelum dependensi di-cache, build berikutnya akan lebih cepat. Selain itu, jika Anda perlu menentukan argumen yang berbeda untuk perintah build, Anda dapat melakukannya di akhir perintah di posisi ``. Misalnya, jika Anda ingin membangun versi rilis yang dioptimalkan, Anda akan menjalankan perintah di atas diikuti oleh `--release`. Hasil eksekusi akan tersedia pada target folder di sistem anda, dan dapat dijalankan dengan:
+Perlu diingat bahwa pada saat build pertama kali, mungkin memerlukan waktu lebih lama sebelum dependensi di-cache, build berikutnya akan lebih cepat. Selain itu, jika perlu menentukan argumen yang berbeda untuk perintah build, kamu dapat melakukannya di akhir perintah di posisi ``. Misalnya, jika ingin membangun versi rilis yang dioptimalkan, jalankan perintah di atas dan tambahkan `--release`. Hasil eksekusi perintah tersebut akan tersimpan pada target folder di sistem kamu, dan dapat dijalankan dengan:
```sh
target/debug/rustdesk
```
-Atau, jika Anda menjalankan rilis yang dapat dieksekusi:
+Atau, jika kamu menjalankan rilis yang dapat dieksekusi:
```sh
target/release/rustdesk
```
-Harap pastikan bahwa Anda menjalankan perintah ini dari root repositori RustDesk, jika tidak, aplikasi mungkin tidak dapat menemukan sumber daya yang diperlukan. Perhatikan juga perintah cargo seperti `install` atau `run` saat ini tidak didukung melalui metode ini karena mereka akan menginstal atau menjalankan program di dalam container bukan pada host.
+Harap pastikan bahwa kamu menjalankan perintah ini dari repositori root RustDesk, jika tidak demikian, aplikasi mungkin tidak dapat menemukan sumber yang diperlukan. Dan juga, perintah cargo seperti `install` atau `run` saat ini tidak didukung melalui metode ini karena, proses menginstal atau menjalankan program terjadi di dalam container bukan pada host.
## Struktur File
From cabfdccfa4a43f18d875fac4ec3d4b99aeaf9dcf Mon Sep 17 00:00:00 2001
From: Ibnul Mutaki
Date: Mon, 21 Aug 2023 21:22:11 +0700
Subject: [PATCH 30/75] fix a little err
---
docs/README-ID.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/README-ID.md b/docs/README-ID.md
index 33dab8445..e4cb5560c 100644
--- a/docs/README-ID.md
+++ b/docs/README-ID.md
@@ -6,7 +6,7 @@
Structure •
Snapshot
[English ] | [Українська ] | [česky ] | [中文 ] | [Magyar ] | [Español ] | [فارسی ] | [Français ] | [Deutsch ] | [Polski ] | [Suomi ] | [മലയാളം ] | [日本語 ] | [Nederlands ] | [Italiano ] | [Русский ] | [Português (Brasil) ] | [Esperanto ] | [한국어 ] | [العربي ] | [Tiếng Việt ] | [Ελληνικά ]
- Kami membutuhkan bantuan kamu untuk menterjemahkan file README dan RustDesk UI ke Bahasa Indonesia
+ Kami membutuhkan bantuanmu untuk menterjemahkan file README dan RustDesk UI ke Bahasa Indonesia
Mari mengobrol bersama kami: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
From afe12154a240823c5085c97058417f2de587a859 Mon Sep 17 00:00:00 2001
From: jimmyGALLAND <64364019+jimmyGALLAND@users.noreply.github.com>
Date: Mon, 21 Aug 2023 16:26:23 +0200
Subject: [PATCH 31/75] Improve some translate fr.rs
---
src/lang/fr.rs | 44 ++++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/src/lang/fr.rs b/src/lang/fr.rs
index 16e0585ee..f9d711ccd 100644
--- a/src/lang/fr.rs
+++ b/src/lang/fr.rs
@@ -75,7 +75,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Do you want to enter again?", "Voulez-vous participer à nouveau ?"),
("Connection Error", "Erreur de connexion"),
("Error", "Erreur"),
- ("Reset by the peer", "La connexion a été fermée par la machine distante"),
+ ("Reset by the peer", "La connexion a été fermée par l'appareil distant"),
("Connecting...", "Connexion..."),
("Connection in progress. Please wait.", "Connexion en cours. Veuillez patienter."),
("Please try 1 minute later", "Réessayez dans une minute"),
@@ -92,8 +92,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Refresh File", "Rafraîchir le contenu"),
("Local", "Local"),
("Remote", "Distant"),
- ("Remote Computer", "Ordinateur distant"),
- ("Local Computer", "Ordinateur local"),
+ ("Remote Computer", "Appareil distant"),
+ ("Local Computer", "Appareil local"),
("Confirm Delete", "Confirmer la suppression"),
("Delete", "Supprimer"),
("Properties", "Propriétés"),
@@ -129,9 +129,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Show remote cursor", "Afficher le curseur distant"),
("Show quality monitor", "Afficher le moniteur de qualité"),
("Disable clipboard", "Désactiver le presse-papier"),
- ("Lock after session end", "Verrouiller l'ordinateur distant après la déconnexion"),
+ ("Lock after session end", "Verrouiller l'appareil distant après la déconnexion"),
("Insert", "Envoyer"),
- ("Insert Lock", "Verrouiller l'ordinateur distant"),
+ ("Insert Lock", "Verrouiller l'appareil distant"),
("Refresh", "Rafraîchir l'écran"),
("ID does not exist", "L'ID n'existe pas"),
("Failed to connect to rendezvous server", "Échec de la connexion au serveur rendezvous"),
@@ -188,7 +188,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Relayed and encrypted connection", "Connexion relais chiffrée"),
("Direct and unencrypted connection", "Connexion directe non chiffrée"),
("Relayed and unencrypted connection", "Connexion relais non chiffrée"),
- ("Enter Remote ID", "Entrer l'ID de l'appareil à distance"),
+ ("Enter Remote ID", "Entrer l'ID de l'appareil distant"),
("Enter your password", "Entrer votre mot de passe"),
("Logging in...", "En cours de connexion ..."),
("Enable RDP session sharing", "Activer le partage de session RDP"),
@@ -210,7 +210,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Settings", "Paramètres"),
("Username", " Nom d'utilisateur"),
("Invalid port", "Port invalide"),
- ("Closed manually by the peer", "Fermé manuellement par la machine distante"),
+ ("Closed manually by the peer", "Fermé manuellement par l'appareil distant"),
("Enable remote configuration modification", "Autoriser la modification de la configuration à distance"),
("Run without install", "Exécuter sans installer"),
("Connect via relay", "Connexion via relais"),
@@ -223,12 +223,12 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Verification code", "Code de vérification"),
("verification_tip", "Un nouvel appareil a été détecté et un code de vérification a été envoyé à l'adresse e-mail enregistrée, entrez le code de vérification pour continuer la connexion."),
("Logout", "Déconnexion"),
- ("Tags", "Étiqueter"),
+ ("Tags", "Étiquettes"),
("Search ID", "Rechercher un ID"),
("whitelist_sep", "Vous pouvez utiliser une virgule, un point-virgule, un espace ou une nouvelle ligne comme séparateur"),
("Add ID", "Ajouter un ID"),
("Add Tag", "Ajouter une balise"),
- ("Unselect all tags", "Désélectionner toutes les balises"),
+ ("Unselect all tags", "Désélectionner toutes les étiquettes"),
("Network error", "Erreur réseau"),
("Username missed", "Nom d'utilisateur manquant"),
("Password missed", "Mot de passe manquant"),
@@ -301,9 +301,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Succeeded", "Succès"),
("Someone turns on privacy mode, exit", "Quelqu'un active le mode de confidentialité, quittez"),
("Unsupported", "Non pris en charge"),
- ("Peer denied", "Machine distante refusée"),
+ ("Peer denied", "Appareil distant refusé"),
("Please install plugins", "Veuillez installer les plugins"),
- ("Peer exit", "Machine distante déconnectée"),
+ ("Peer exit", "Appareil distant déconnecté"),
("Failed to turn off", "Échec de la désactivation"),
("Turned off", "Désactivé"),
("In privacy mode", "en mode privé"),
@@ -382,7 +382,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Write a message", "Ecrire un message"),
("Prompt", ""),
("Please wait for confirmation of UAC...", "Veuillez attendre la confirmation de l'UAC..."),
- ("elevated_foreground_window_tip", "La fenêtre actuelle que la machine distante nécessite des privilèges plus élevés pour fonctionner, elle ne peut donc pas être atteinte par la souris et le clavier. Vous pouvez demander à l'utilisateur distant de réduire la fenêtre actuelle ou de cliquer sur le bouton d'élévation dans la fenêtre de gestion des connexions. Pour éviter ce problème, il est recommandé d'installer le logiciel sur l'appareil distant."),
+ ("elevated_foreground_window_tip", "La fenêtre actuelle que l'appareil distant nécessite des privilèges plus élevés pour fonctionner, elle ne peut donc pas être atteinte par la souris et le clavier. Vous pouvez demander à l'utilisateur distant de réduire la fenêtre actuelle ou de cliquer sur le bouton d'élévation dans la fenêtre de gestion des connexions. Pour éviter ce problème, il est recommandé d'installer le logiciel sur l'appareil distant."),
("Disconnected", "Déconnecté"),
("Other", "Divers"),
("Confirm before closing multiple tabs", "Confirmer avant de fermer plusieurs onglets"),
@@ -392,7 +392,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Wayland requires Ubuntu 21.04 or higher version.", "Wayland nécessite Ubuntu 21.04 ou une version supérieure."),
("Wayland requires higher version of linux distro. Please try X11 desktop or change your OS.", "Wayland nécessite une version supérieure de la distribution Linux. Veuillez essayer le bureau X11 ou changer votre système d'exploitation."),
("JumpLink", "Afficher"),
- ("Please Select the screen to be shared(Operate on the peer side).", "Veuillez sélectionner l'écran à partager (côté machine distante)."),
+ ("Please Select the screen to be shared(Operate on the peer side).", "Veuillez sélectionner l'écran à partager (côté appareil distant)."),
("Show RustDesk", "Afficher RustDesk"),
("This PC", "Ce PC"),
("or", "ou"),
@@ -454,7 +454,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Voice call", "Appel voix"),
("Text chat", "Conversation textuelfle"),
("Stop voice call", "Stopper l'appel voix"),
- ("relay_hint_tip", "Il se peut qu'il ne doit pas possible de se connecter directement, vous pouvez essayer de vous connecter via un relais. \nEn outre, si vous souhaitez utiliser directement le relais, vous pouvez ajouter le suffixe \"/r\" à l'ID ou sélectionner l'option \"Toujours se connecter via le relais\" dans la fiche pair."),
+ ("relay_hint_tip", "Il se peut qu'il ne doit pas possible de se connecter directement, vous pouvez essayer de vous connecter via un relais. \nEn outre, si vous souhaitez utiliser directement le relais, vous pouvez ajouter le suffixe \"/r\" à l'ID ou sélectionner l'option \"Toujours se connecter via le relais\" dans la fiche appareils distants."),
("Reconnect", "Se reconnecter"),
("Codec", "Codec"),
("Resolution", "Résolution"),
@@ -470,14 +470,14 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Maximize", "Maximiser"),
("Your Device", "Votre appareil"),
("empty_recent_tip", "Oups, pas de sessions récentes!\nIl est temps d'en prévoir une nouvelle."),
- ("empty_favorite_tip", "Vous n'avez pas encore de pairs favoris?\nTrouvons quelqu'un avec qui vous connecter et ajoutez-le à vos favoris!"),
- ("empty_lan_tip", "Oh non, il semble que nous n'ayons pas encore de pairs découverts."),
- ("empty_address_book_tip", "Ouh là là! il semble qu'il n'y ait actuellement aucun pair répertorié dans votre carnet d'adresses."),
+ ("empty_favorite_tip", "Vous n'avez pas encore d'appareils distants favorits?\nTrouvons quelqu'un avec qui vous connecter et ajoutez-la à vos favoris!"),
+ ("empty_lan_tip", "Oh non, il semble que nous n'ayons pas encore d'appareil réseaux local découverts."),
+ ("empty_address_book_tip", "Ouh là là! il semble qu'il n'y ait actuellement aucun appareil distant répertorié dans votre carnet d'adresses."),
("eg: admin", "ex: admin"),
("Empty Username", "Nom d'utilisation non spécifié"),
("Empty Password", "Mot de passe non spécifié"),
("Me", "Moi"),
- ("identical_file_tip", "Ce fichier est identique à celui du pair."),
+ ("identical_file_tip", "Ce fichier est identique à celui de l'appareil distant."),
("show_monitors_tip", "Afficher les moniteurs dans la barre d'outils"),
("View Mode", "Mode vue"),
("login_linux_tip", "Se connecter au compte Linux distant"),
@@ -498,8 +498,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Fingerprint", "Empreinte digitale"),
("Copy Fingerprint", "Copier empreinte digitale"),
("no fingerprints", "Pas d'empreintes digitales"),
- ("Select a peer", "Sélectionnez la machine distante"),
- ("Select peers", "Sélectionnez des machines distantes"),
+ ("Select a peer", "Sélectionnez l'appareil distant"),
+ ("Select peers", "Sélectionnez des appareils distants"),
("Plugins", "Plugins"),
("Uninstall", "Désinstaller"),
("Update", "Mise à jour"),
@@ -523,7 +523,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Stop", "Stopper"),
("exceed_max_devices", "Vous avez atteint le nombre maximal d'appareils gérés."),
("Sync with recent sessions", "Synchroniser avec les sessions récentes"),
- ("Sort tags", "Trier les Tags"),
+ ("Sort tags", "Trier les étiquettes"),
("Open connection in new tab", "Ouvrir la connexion dans un nouvel onglet"),
("Move tab to new window", "Déplacer l'onglet vers une nouvelle fenêtre"),
("Can not be empty", "Ne peux pas être vide"),
@@ -534,7 +534,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Grid View", "Vue Grille"),
("List View", "Vue Liste"),
("Select", "Sélectionner"),
- ("Toggle Tags", "Basculer vers les Tags"),
+ ("Toggle Tags", "Basculer vers les étiquettes"),
("pull_ab_failed_tip", "Impossible d'actualiser le carnet d'adresses"),
("push_ab_failed_tip", "Échec de la synchronisation du carnet d'adresses"),
("synced_peer_readded_tip", "Les appareils qui étaient présents dans les sessions récentes seront synchronisés avec le carnet d'adresses."),
From d8ace7e38bd598aba3c1bc8ae15e423d190e660c Mon Sep 17 00:00:00 2001
From: Jimmy GALLAND
Date: Mon, 21 Aug 2023 22:42:16 +0200
Subject: [PATCH 32/75] fix peer tab page count selected translate
---
flutter/lib/common/widgets/peer_tab_page.dart | 2 +-
src/lang/fr.rs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/flutter/lib/common/widgets/peer_tab_page.dart b/flutter/lib/common/widgets/peer_tab_page.dart
index 120ea7ff1..3f4161477 100644
--- a/flutter/lib/common/widgets/peer_tab_page.dart
+++ b/flutter/lib/common/widgets/peer_tab_page.dart
@@ -426,7 +426,7 @@ class _PeerTabPageState extends State
Widget selectionCount(int count) {
return Align(
alignment: Alignment.center,
- child: Text('$count selected'),
+ child: Text('$count ${translate('Selected')}'),
);
}
diff --git a/src/lang/fr.rs b/src/lang/fr.rs
index f9d711ccd..fdf9cdf51 100644
--- a/src/lang/fr.rs
+++ b/src/lang/fr.rs
@@ -274,7 +274,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Chat", "Discuter"),
("Total", "Total"),
("items", "éléments"),
- ("Selected", "Sélectionné"),
+ ("Selected", "Sélectionné(s)"),
("Screen Capture", "Capture d'écran"),
("Input Control", "Contrôle de saisie"),
("Audio Capture", "Capture audio"),
From 83d9cb55f1ae5e622ae689ac8f136d283e870e5b Mon Sep 17 00:00:00 2001
From: 21pages
Date: Tue, 22 Aug 2023 08:54:01 +0800
Subject: [PATCH 33/75] filter tags with union, not intersection
Signed-off-by: 21pages
---
flutter/lib/common/widgets/peers_view.dart | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/flutter/lib/common/widgets/peers_view.dart b/flutter/lib/common/widgets/peers_view.dart
index b4fd8e1d4..0e4898fc2 100644
--- a/flutter/lib/common/widgets/peers_view.dart
+++ b/flutter/lib/common/widgets/peers_view.dart
@@ -421,15 +421,12 @@ class AddressBookPeersView extends BasePeersView {
if (selectedTags.isEmpty) {
return true;
}
- if (idents.isEmpty) {
- return false;
- }
for (final tag in selectedTags) {
- if (!idents.contains(tag)) {
- return false;
+ if (idents.contains(tag)) {
+ return true;
}
}
- return true;
+ return false;
}
}
From a48532d0b1c36f5fa1b5933e8bee3f52b50b9ebd Mon Sep 17 00:00:00 2001
From: 21pages
Date: Tue, 22 Aug 2023 09:01:11 +0800
Subject: [PATCH 34/75] fix mobile missing tag color
Signed-off-by: 21pages
---
flutter/lib/common/widgets/peer_card.dart | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart
index 889ba3fbe..fd558c68c 100644
--- a/flutter/lib/common/widgets/peer_card.dart
+++ b/flutter/lib/common/widgets/peer_card.dart
@@ -66,7 +66,7 @@ class _PeerCardState extends State<_PeerCard>
final name =
'${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}';
final PeerTabModel peerTabModel = Provider.of(context);
- return Card(
+ final child = Card(
margin: EdgeInsets.symmetric(horizontal: 2),
child: GestureDetector(
onTap: () {
@@ -115,6 +115,23 @@ class _PeerCardState extends State<_PeerCard>
],
),
)));
+ final colors = _frontN(peer.tags, 25).map((e) => str2color2(e)).toList();
+ return Tooltip(
+ message: peer.tags.isNotEmpty
+ ? '${translate('Tags')}: ${peer.tags.join(', ')}'
+ : '',
+ child: Stack(children: [
+ child,
+ if (colors.isNotEmpty)
+ Positioned(
+ top: 2,
+ right: 10,
+ child: CustomPaint(
+ painter: TagPainter(radius: 3, colors: colors),
+ ),
+ )
+ ]),
+ );
}
Widget _buildDesktop() {
From 5a6a7e8d82c5e0022ce72731856331fa7769511e Mon Sep 17 00:00:00 2001
From: 21pages
Date: Tue, 22 Aug 2023 11:41:57 +0800
Subject: [PATCH 35/75] mobile use _buildPeerTile
Signed-off-by: 21pages
---
flutter/lib/common/widgets/peer_card.dart | 224 +++++++++-------------
1 file changed, 93 insertions(+), 131 deletions(-)
diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart
index fd558c68c..8bb4fdfdb 100644
--- a/flutter/lib/common/widgets/peer_card.dart
+++ b/flutter/lib/common/widgets/peer_card.dart
@@ -63,75 +63,29 @@ class _PeerCardState extends State<_PeerCard>
Widget _buildMobile() {
final peer = super.widget.peer;
- final name =
- '${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}';
final PeerTabModel peerTabModel = Provider.of(context);
- final child = Card(
+ return Card(
margin: EdgeInsets.symmetric(horizontal: 2),
child: GestureDetector(
- onTap: () {
- if (peerTabModel.multiSelectionMode) {
- peerTabModel.select(peer);
- } else {
- if (!isWebDesktop) {
- connectInPeerTab(context, peer.id, widget.tab);
- }
- }
- },
- onDoubleTap: isWebDesktop
- ? () => connectInPeerTab(context, peer.id, widget.tab)
- : null,
- onLongPress: () {
+ onTap: () {
+ if (peerTabModel.multiSelectionMode) {
peerTabModel.select(peer);
- },
- child: Container(
+ } else {
+ if (!isWebDesktop) {
+ connectInPeerTab(context, peer.id, widget.tab);
+ }
+ }
+ },
+ onDoubleTap: isWebDesktop
+ ? () => connectInPeerTab(context, peer.id, widget.tab)
+ : null,
+ onLongPress: () {
+ peerTabModel.select(peer);
+ },
+ child: Container(
padding: EdgeInsets.only(left: 12, top: 8, bottom: 8),
- child: Row(
- children: [
- Container(
- width: 50,
- height: 50,
- decoration: BoxDecoration(
- color: str2color('${peer.id}${peer.platform}', 0x7f),
- borderRadius: BorderRadius.circular(4),
- ),
- padding: const EdgeInsets.all(6),
- child: getPlatformImage(peer.platform)),
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(children: [
- getOnline(4, peer.online),
- Text(peer.alias.isEmpty
- ? formatID(peer.id)
- : peer.alias)
- ]),
- Text(name)
- ],
- ).paddingOnly(left: 8.0),
- ),
- checkBoxOrActionMoreMobile(peer),
- ],
- ),
- )));
- final colors = _frontN(peer.tags, 25).map((e) => str2color2(e)).toList();
- return Tooltip(
- message: peer.tags.isNotEmpty
- ? '${translate('Tags')}: ${peer.tags.join(', ')}'
- : '',
- child: Stack(children: [
- child,
- if (colors.isNotEmpty)
- Positioned(
- top: 2,
- right: 10,
- child: CustomPaint(
- painter: TagPainter(radius: 3, colors: colors),
- ),
- )
- ]),
- );
+ child: _buildPeerTile(context, peer, null)),
+ ));
}
Widget _buildDesktop() {
@@ -178,87 +132,95 @@ class _PeerCardState extends State<_PeerCard>
}
Widget _buildPeerTile(
- BuildContext context, Peer peer, Rx deco) {
+ BuildContext context, Peer peer, Rx? deco) {
final name =
'${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}';
final greyStyle = TextStyle(
fontSize: 11,
color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6));
- final child = Obx(
- () => Container(
- foregroundDecoration: deco.value,
- child: Row(
- mainAxisSize: MainAxisSize.max,
- children: [
- Container(
- decoration: BoxDecoration(
- color: str2color('${peer.id}${peer.platform}', 0x7f),
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(_tileRadius),
- bottomLeft: Radius.circular(_tileRadius),
- ),
- ),
- alignment: Alignment.center,
- width: 42,
- child: getPlatformImage(peer.platform, size: 30).paddingAll(6),
- ),
- Expanded(
- child: Container(
- decoration: BoxDecoration(
- color: Theme.of(context).colorScheme.background,
- borderRadius: BorderRadius.only(
- topRight: Radius.circular(_tileRadius),
- bottomRight: Radius.circular(_tileRadius),
+ final child = Row(
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ Container(
+ decoration: BoxDecoration(
+ color: str2color('${peer.id}${peer.platform}', 0x7f),
+ borderRadius: isMobile
+ ? BorderRadius.circular(_tileRadius)
+ : BorderRadius.only(
+ topLeft: Radius.circular(_tileRadius),
+ bottomLeft: Radius.circular(_tileRadius),
),
- ),
- child: Row(
- children: [
- Expanded(
- child: Column(
- children: [
- Row(children: [
- getOnline(8, peer.online),
- Expanded(
- child: Text(
- peer.alias.isEmpty
- ? formatID(peer.id)
- : peer.alias,
- overflow: TextOverflow.ellipsis,
- style: Theme.of(context).textTheme.titleSmall,
- )),
- ]).marginOnly(bottom: 0, top: 2),
- Align(
- alignment: Alignment.centerLeft,
- child: Text(
- name,
- style: greyStyle,
- textAlign: TextAlign.start,
- overflow: TextOverflow.ellipsis,
- ),
- ),
- ],
- ).marginOnly(top: 2),
- ),
- checkBoxOrActionMoreDesktop(peer, isTile: true),
- ],
- ).paddingOnly(left: 10.0, top: 3.0),
- ),
- )
- ],
+ ),
+ alignment: Alignment.center,
+ width: isMobile ? 50 : 42,
+ height: isMobile ? 50 : null,
+ child: getPlatformImage(peer.platform, size: isMobile ? 38 : 30)
+ .paddingAll(6),
),
- ),
+ Expanded(
+ child: Container(
+ decoration: BoxDecoration(
+ color: Theme.of(context).colorScheme.background,
+ borderRadius: BorderRadius.only(
+ topRight: Radius.circular(_tileRadius),
+ bottomRight: Radius.circular(_tileRadius),
+ ),
+ ),
+ child: Row(
+ children: [
+ Expanded(
+ child: Column(
+ children: [
+ Row(children: [
+ getOnline(isMobile ? 4 : 8, peer.online),
+ Expanded(
+ child: Text(
+ peer.alias.isEmpty ? formatID(peer.id) : peer.alias,
+ overflow: TextOverflow.ellipsis,
+ style: Theme.of(context).textTheme.titleSmall,
+ )),
+ ]).marginOnly(top: isMobile ? 0 : 2),
+ Align(
+ alignment: Alignment.centerLeft,
+ child: Text(
+ name,
+ style: isMobile ? null : greyStyle,
+ textAlign: TextAlign.start,
+ overflow: TextOverflow.ellipsis,
+ ),
+ ),
+ ],
+ ).marginOnly(top: 2),
+ ),
+ isMobile
+ ? checkBoxOrActionMoreMobile(peer)
+ : checkBoxOrActionMoreDesktop(peer, isTile: true),
+ ],
+ ).paddingOnly(left: 10.0, top: 3.0),
+ ),
+ )
+ ],
);
final colors = _frontN(peer.tags, 25).map((e) => str2color2(e)).toList();
return Tooltip(
- message: peer.tags.isNotEmpty
- ? '${translate('Tags')}: ${peer.tags.join(', ')}'
- : '',
+ message: isMobile
+ ? ''
+ : peer.tags.isNotEmpty
+ ? '${translate('Tags')}: ${peer.tags.join(', ')}'
+ : '',
child: Stack(children: [
- child,
+ deco == null
+ ? child
+ : Obx(
+ () => Container(
+ foregroundDecoration: deco.value,
+ child: child,
+ ),
+ ),
if (colors.isNotEmpty)
Positioned(
top: 2,
- right: 10,
+ right: isMobile ? 20 : 10,
child: CustomPaint(
painter: TagPainter(radius: 3, colors: colors),
),
From b27c3ff169b56fd6d44c87179897f10c695c4c0b Mon Sep 17 00:00:00 2001
From: 21pages
Date: Tue, 22 Aug 2023 19:07:01 +0800
Subject: [PATCH 36/75] change tag color
Signed-off-by: 21pages
---
flutter/lib/common.dart | 16 ++-
flutter/lib/common/widgets/address_book.dart | 22 +++-
flutter/lib/common/widgets/peer_card.dart | 6 +-
flutter/lib/models/ab_model.dart | 117 ++++++++++++-------
flutter/pubspec.yaml | 1 +
libs/hbb_common/src/config.rs | 6 +
src/lang/ca.rs | 1 +
src/lang/cn.rs | 1 +
src/lang/cs.rs | 1 +
src/lang/da.rs | 1 +
src/lang/de.rs | 1 +
src/lang/el.rs | 1 +
src/lang/eo.rs | 1 +
src/lang/es.rs | 1 +
src/lang/fa.rs | 1 +
src/lang/fr.rs | 1 +
src/lang/hu.rs | 1 +
src/lang/id.rs | 1 +
src/lang/it.rs | 1 +
src/lang/ja.rs | 1 +
src/lang/ko.rs | 1 +
src/lang/kz.rs | 1 +
src/lang/lt.rs | 1 +
src/lang/nl.rs | 1 +
src/lang/pl.rs | 1 +
src/lang/pt_PT.rs | 1 +
src/lang/ptbr.rs | 1 +
src/lang/ro.rs | 1 +
src/lang/ru.rs | 1 +
src/lang/sk.rs | 1 +
src/lang/sl.rs | 1 +
src/lang/sq.rs | 1 +
src/lang/sr.rs | 1 +
src/lang/sv.rs | 1 +
src/lang/template.rs | 1 +
src/lang/th.rs | 1 +
src/lang/tr.rs | 1 +
src/lang/tw.rs | 1 +
src/lang/ua.rs | 1 +
src/lang/vn.rs | 1 +
40 files changed, 152 insertions(+), 50 deletions(-)
diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart
index eb21ac821..48323d5fa 100644
--- a/flutter/lib/common.dart
+++ b/flutter/lib/common.dart
@@ -1077,7 +1077,7 @@ Color str2color(String str, [alpha = 0xFF]) {
return Color((hash & 0xFF7FFF) | (alpha << 24));
}
-Color str2color2(String str, [alpha = 0xFF]) {
+Color str2color2(String str, {List existing = const []}) {
Map colorMap = {
"red": Colors.red,
"green": Colors.green,
@@ -1094,10 +1094,10 @@ Color str2color2(String str, [alpha = 0xFF]) {
};
final color = colorMap[str.toLowerCase()];
if (color != null) {
- return color.withAlpha(alpha);
+ return color.withAlpha(0xFF);
}
if (str.toLowerCase() == 'yellow') {
- return Colors.yellow.withAlpha(alpha);
+ return Colors.yellow.withAlpha(0xFF);
}
var hash = 0;
for (var i = 0; i < str.length; i++) {
@@ -1105,7 +1105,15 @@ Color str2color2(String str, [alpha = 0xFF]) {
}
List colorList = colorMap.values.toList();
hash = hash % colorList.length;
- return colorList[hash].withAlpha(alpha);
+ var result = colorList[hash].withAlpha(0xFF);
+ if (existing.contains(result.value)) {
+ Color? notUsed =
+ colorList.firstWhereOrNull((e) => !existing.contains(e.value));
+ if (notUsed != null) {
+ result = notUsed;
+ }
+ }
+ return result;
}
const K = 1024;
diff --git a/flutter/lib/common/widgets/address_book.dart b/flutter/lib/common/widgets/address_book.dart
index 86a5b2c55..292266ae7 100644
--- a/flutter/lib/common/widgets/address_book.dart
+++ b/flutter/lib/common/widgets/address_book.dart
@@ -7,6 +7,7 @@ import 'package:flutter_hbb/models/ab_model.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import '../../desktop/widgets/material_mod_popup_menu.dart' as mod_menu;
import 'package:get/get.dart';
+import 'package:flex_color_picker/flex_color_picker.dart';
import '../../common.dart';
import 'dialog.dart';
@@ -513,7 +514,7 @@ class AddressBookTag extends StatelessWidget {
child: Obx(() => Container(
decoration: BoxDecoration(
color: tags.contains(name)
- ? str2color2(name, 0xFF)
+ ? gFFI.abModel.getTagColor(name)
: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(4)),
margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
@@ -528,7 +529,7 @@ class AddressBookTag extends StatelessWidget {
shape: BoxShape.circle,
color: tags.contains(name)
? Colors.white
- : str2color2(name)),
+ : gFFI.abModel.getTagColor(name)),
).marginOnly(right: radius / 2),
Expanded(
child: Text(name,
@@ -568,6 +569,23 @@ class AddressBookTag extends StatelessWidget {
Future.delayed(Duration.zero, () => Get.back());
});
}),
+ getEntry(translate(translate('Change Color')), () async {
+ final model = gFFI.abModel;
+ Color oldColor = model.getTagColor(name);
+ Color newColor = await showColorPickerDialog(
+ context,
+ oldColor,
+ pickersEnabled: {
+ ColorPickerType.accent: false,
+ ColorPickerType.wheel: true,
+ },
+ showColorCode: true,
+ );
+ if (oldColor != newColor) {
+ model.setTagColor(name, newColor);
+ model.pushAb();
+ }
+ }),
getEntry(translate("Delete"), () {
gFFI.abModel.deleteTag(name);
gFFI.abModel.pushAb();
diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart
index 8bb4fdfdb..74f0dcb31 100644
--- a/flutter/lib/common/widgets/peer_card.dart
+++ b/flutter/lib/common/widgets/peer_card.dart
@@ -201,7 +201,8 @@ class _PeerCardState extends State<_PeerCard>
)
],
);
- final colors = _frontN(peer.tags, 25).map((e) => str2color2(e)).toList();
+ final colors =
+ _frontN(peer.tags, 25).map((e) => gFFI.abModel.getTagColor(e)).toList();
return Tooltip(
message: isMobile
? ''
@@ -311,7 +312,8 @@ class _PeerCardState extends State<_PeerCard>
),
);
- final colors = _frontN(peer.tags, 25).map((e) => str2color2(e)).toList();
+ final colors =
+ _frontN(peer.tags, 25).map((e) => gFFI.abModel.getTagColor(e)).toList();
return Tooltip(
message: peer.tags.isNotEmpty
? '${translate('Tags')}: ${peer.tags.join(', ')}'
diff --git a/flutter/lib/models/ab_model.dart b/flutter/lib/models/ab_model.dart
index f5e217472..e91e42ef9 100644
--- a/flutter/lib/models/ab_model.dart
+++ b/flutter/lib/models/ab_model.dart
@@ -28,6 +28,7 @@ class AbModel {
final pullError = "".obs;
final pushError = "".obs;
final tags = [].obs;
+ final RxMap tagColors = Map.fromEntries([]).obs;
final peers = List.empty(growable: true).obs;
final sortTags = shouldSortTags().obs;
final retrying = false.obs;
@@ -80,10 +81,11 @@ class AbModel {
if (resp.body.toLowerCase() == "null") {
// normal reply, emtpy ab return null
tags.clear();
+ tagColors.clear();
peers.clear();
} else if (resp.body.isNotEmpty) {
Map json =
- _jsonDecode(utf8.decode(resp.bodyBytes), resp.statusCode);
+ _jsonDecodeResp(utf8.decode(resp.bodyBytes), resp.statusCode);
if (json.containsKey('error')) {
throw json['error'];
} else if (json.containsKey('data')) {
@@ -93,26 +95,7 @@ class AbModel {
} catch (e) {}
final data = jsonDecode(json['data']);
if (data != null) {
- final oldOnlineIDs =
- peers.where((e) => e.online).map((e) => e.id).toList();
- tags.clear();
- peers.clear();
- if (data['tags'] is List) {
- tags.value = data['tags'];
- }
- if (data['peers'] is List) {
- for (final peer in data['peers']) {
- peers.add(Peer.fromJson(peer));
- }
- }
- if (isFull(false)) {
- peers.removeRange(licensedDevices, peers.length);
- }
- // restore online
- peers
- .where((e) => oldOnlineIDs.contains(e.id))
- .map((e) => e.online = true)
- .toList();
+ _deserialize(data);
_saveCache(); // save on success
}
}
@@ -242,10 +225,7 @@ class AbModel {
final api = "${await bind.mainGetApiServer()}/api/ab";
var authHeaders = getHttpHeaders();
authHeaders['Content-Type'] = "application/json";
- final peersJsonData = peers.map((e) => e.toAbUploadJson()).toList();
- final body = jsonEncode({
- "data": jsonEncode({"tags": tags, "peers": peersJsonData})
- });
+ final body = jsonEncode(_serialize());
http.Response resp;
// support compression
if (licensedDevices > 0 && body.length > 1024) {
@@ -261,7 +241,7 @@ class AbModel {
ret = true;
_saveCache();
} else {
- Map json = _jsonDecode(resp.body, resp.statusCode);
+ Map json = _jsonDecodeResp(resp.body, resp.statusCode);
if (json.containsKey('error')) {
throw json['error'];
} else if (resp.statusCode == 200) {
@@ -318,6 +298,7 @@ class AbModel {
void deleteTag(String tag) {
gFFI.abModel.selectedTags.remove(tag);
tags.removeWhere((element) => element == tag);
+ tagColors.remove(tag);
for (var peer in peers) {
if (peer.tags.isEmpty) {
continue;
@@ -353,6 +334,11 @@ class AbModel {
}
}).toList();
}
+ int? oldColor = tagColors[oldTag];
+ if (oldColor != null) {
+ tagColors.remove(oldTag);
+ tagColors.addAll({newTag: oldColor});
+ }
}
void unsetSelectedTags() {
@@ -368,6 +354,20 @@ class AbModel {
}
}
+ Color getTagColor(String tag) {
+ int? colorValue = tagColors[tag];
+ if (colorValue != null) {
+ return Color(colorValue);
+ }
+ return str2color2(tag, existing: tagColors.values.toList());
+ }
+
+ setTagColor(String tag, Color color) {
+ if (tags.contains(tag)) {
+ tagColors[tag] = color.value;
+ }
+ }
+
void merge(Peer r, Peer p) {
p.hash = r.hash.isEmpty ? p.hash : r.hash;
p.username = r.username.isEmpty ? p.username : r.username;
@@ -467,12 +467,10 @@ class AbModel {
_saveCache() {
try {
- final peersJsonData = peers.map((e) => e.toAbUploadJson()).toList();
- final m = {
+ var m = _serialize();
+ m.addAll({
"access_token": bind.mainGetLocalOption(key: 'access_token'),
- "peers": peersJsonData,
- "tags": tags.map((e) => e.toString()).toList(),
- };
+ });
bind.mainSaveAb(json: jsonEncode(m));
} catch (e) {
debugPrint('ab save:$e');
@@ -488,22 +486,13 @@ class AbModel {
final cache = await bind.mainLoadAb();
final data = jsonDecode(cache);
if (data == null || data['access_token'] != access_token) return;
- tags.clear();
- peers.clear();
- if (data['tags'] is List) {
- tags.value = data['tags'];
- }
- if (data['peers'] is List) {
- for (final peer in data['peers']) {
- peers.add(Peer.fromJson(peer));
- }
- }
+ _deserialize(data);
} catch (e) {
debugPrint("load ab cache: $e");
}
}
- Map _jsonDecode(String body, int statusCode) {
+ Map _jsonDecodeResp(String body, int statusCode) {
try {
Map json = jsonDecode(body);
return json;
@@ -516,6 +505,50 @@ class AbModel {
}
}
+ Map _serialize() {
+ final peersJsonData = peers.map((e) => e.toAbUploadJson()).toList();
+ final tagColorJsonData = jsonEncode(tagColors);
+ return {
+ "tags": tags,
+ "peers": peersJsonData,
+ "tag_colors": tagColorJsonData
+ };
+ }
+
+ _deserialize(dynamic data) {
+ if (data == null) return;
+ final oldOnlineIDs = peers.where((e) => e.online).map((e) => e.id).toList();
+ tags.clear();
+ tagColors.clear();
+ peers.clear();
+ if (data['tags'] is List) {
+ tags.value = data['tags'];
+ }
+ if (data['peers'] is List) {
+ for (final peer in data['peers']) {
+ peers.add(Peer.fromJson(peer));
+ }
+ }
+ if (isFull(false)) {
+ peers.removeRange(licensedDevices, peers.length);
+ }
+ // restore online
+ peers
+ .where((e) => oldOnlineIDs.contains(e.id))
+ .map((e) => e.online = true)
+ .toList();
+ if (data['tag_colors'] is String) {
+ Map map = jsonDecode(data['tag_colors']);
+ tagColors.value = Map.from(map);
+ }
+ // add color to tag
+ final tagsWithoutColor =
+ tags.toList().where((e) => !tagColors.containsKey(e)).toList();
+ for (var t in tagsWithoutColor) {
+ tagColors[t] = str2color2(t, existing: tagColors.values.toList()).value;
+ }
+ }
+
reSyncToast(Future future) {
if (!shouldSyncAb()) return;
Future.delayed(Duration.zero, () async {
diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml
index fc0be7018..04af8f92f 100644
--- a/flutter/pubspec.yaml
+++ b/flutter/pubspec.yaml
@@ -97,6 +97,7 @@ dependencies:
dropdown_button2: ^2.0.0
uuid: ^3.0.7
auto_size_text_field: ^2.2.1
+ flex_color_picker: ^3.3.0
dev_dependencies:
icons_launcher: ^2.0.4
diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs
index 2cb0072c5..f40ff1463 100644
--- a/libs/hbb_common/src/config.rs
+++ b/libs/hbb_common/src/config.rs
@@ -1525,6 +1525,12 @@ pub struct Ab {
pub peers: Vec,
#[serde(default, deserialize_with = "deserialize_vec_string")]
pub tags: Vec,
+ #[serde(
+ default,
+ deserialize_with = "deserialize_string",
+ skip_serializing_if = "String::is_empty"
+ )]
+ pub tag_colors: String,
}
impl Ab {
diff --git a/src/lang/ca.rs b/src/lang/ca.rs
index 739d5646b..4801abcae 100644
--- a/src/lang/ca.rs
+++ b/src/lang/ca.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/cn.rs b/src/lang/cn.rs
index 34ecdb276..3313537d1 100644
--- a/src/lang/cn.rs
+++ b/src/lang/cn.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "未成功获取地址簿"),
("push_ab_failed_tip", "未成功上传地址簿"),
("synced_peer_readded_tip", "最近会话中存在的设备将会被重新同步到地址簿。"),
+ ("Change Color", "更改颜色"),
].iter().cloned().collect();
}
diff --git a/src/lang/cs.rs b/src/lang/cs.rs
index e32246da7..3d913b0d6 100644
--- a/src/lang/cs.rs
+++ b/src/lang/cs.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Nepodařilo se obnovit adresář"),
("push_ab_failed_tip", "Nepodařilo se synchronizovat adresář se serverem"),
("synced_peer_readded_tip", "Zařízení, která byla přítomna v posledních relacích, budou synchronizována zpět do adresáře."),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/da.rs b/src/lang/da.rs
index 830cb0c45..afaf98386 100644
--- a/src/lang/da.rs
+++ b/src/lang/da.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/de.rs b/src/lang/de.rs
index 53a898a6a..8eb066f30 100644
--- a/src/lang/de.rs
+++ b/src/lang/de.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Aktualisierung des Adressbuchs fehlgeschlagen"),
("push_ab_failed_tip", "Synchronisierung des Adressbuchs mit dem Server fehlgeschlagen"),
("synced_peer_readded_tip", "Die Geräte, die in den letzten Sitzungen vorhanden waren, werden erneut zum Adressbuch hinzugefügt."),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/el.rs b/src/lang/el.rs
index 46f816677..56805e574 100644
--- a/src/lang/el.rs
+++ b/src/lang/el.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/eo.rs b/src/lang/eo.rs
index 8d7f1c873..bcb467839 100644
--- a/src/lang/eo.rs
+++ b/src/lang/eo.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/es.rs b/src/lang/es.rs
index aabbbfd27..5384dfead 100644
--- a/src/lang/es.rs
+++ b/src/lang/es.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "No se ha podido refrescar el directorio"),
("push_ab_failed_tip", "No se ha podido sincronizar el directorio con el servidor"),
("synced_peer_readded_tip", "Los dispositivos presentes en sesiones recientes se sincronizarán con el directorio."),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/fa.rs b/src/lang/fa.rs
index eeb36af3b..fab82f661 100644
--- a/src/lang/fa.rs
+++ b/src/lang/fa.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/fr.rs b/src/lang/fr.rs
index fdf9cdf51..24cc268ee 100644
--- a/src/lang/fr.rs
+++ b/src/lang/fr.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Impossible d'actualiser le carnet d'adresses"),
("push_ab_failed_tip", "Échec de la synchronisation du carnet d'adresses"),
("synced_peer_readded_tip", "Les appareils qui étaient présents dans les sessions récentes seront synchronisés avec le carnet d'adresses."),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/hu.rs b/src/lang/hu.rs
index 2da6bd72e..aaf888d23 100644
--- a/src/lang/hu.rs
+++ b/src/lang/hu.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/id.rs b/src/lang/id.rs
index 45cb3f1c8..a7b12f2ed 100644
--- a/src/lang/id.rs
+++ b/src/lang/id.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Gagal memuat ulang buku alamat"),
("push_ab_failed_tip", "Gagal menyinkronkan buku alamat ke server"),
("synced_peer_readded_tip", "Perangkat yang terdaftar dalam sesi-sesi terbaru akan di-sinkronkan kembali ke buku alamat."),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/it.rs b/src/lang/it.rs
index 4febb9e00..3b8bd8416 100644
--- a/src/lang/it.rs
+++ b/src/lang/it.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Impossibile aggiornare la rubrica"),
("push_ab_failed_tip", "Impossibile sincronizzare la rubrica con il server"),
("synced_peer_readded_tip", "I dispositivi presenti nelle sessioni recenti saranno sincronizzati di nuovo nella rubrica."),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ja.rs b/src/lang/ja.rs
index 4c4d6e141..1a9e8da4f 100644
--- a/src/lang/ja.rs
+++ b/src/lang/ja.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ko.rs b/src/lang/ko.rs
index 91e49be3a..28c34f7e2 100644
--- a/src/lang/ko.rs
+++ b/src/lang/ko.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/kz.rs b/src/lang/kz.rs
index 807b74ba4..2fb2b8b92 100644
--- a/src/lang/kz.rs
+++ b/src/lang/kz.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/lt.rs b/src/lang/lt.rs
index 0cd258b9e..6a8c7e9f5 100644
--- a/src/lang/lt.rs
+++ b/src/lang/lt.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/nl.rs b/src/lang/nl.rs
index c37e95c89..3b08427df 100644
--- a/src/lang/nl.rs
+++ b/src/lang/nl.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/pl.rs b/src/lang/pl.rs
index 923dadc22..67b9d188a 100644
--- a/src/lang/pl.rs
+++ b/src/lang/pl.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs
index 3eb850227..416600eeb 100644
--- a/src/lang/pt_PT.rs
+++ b/src/lang/pt_PT.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs
index 40360be5a..98e469f7e 100644
--- a/src/lang/ptbr.rs
+++ b/src/lang/ptbr.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ro.rs b/src/lang/ro.rs
index 50ae39902..f4d44b3ae 100644
--- a/src/lang/ro.rs
+++ b/src/lang/ro.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ru.rs b/src/lang/ru.rs
index 5830525d9..37fdb2060 100644
--- a/src/lang/ru.rs
+++ b/src/lang/ru.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Невозможно обновить адресную книгу"),
("push_ab_failed_tip", "Невозможно синхронизировать адресную книгу с сервером"),
("synced_peer_readded_tip", "Устройства, присутствовавшие в последних сеансах, будут синхронизированы с адресной книгой."),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sk.rs b/src/lang/sk.rs
index 4b7ced046..8421bd2b0 100644
--- a/src/lang/sk.rs
+++ b/src/lang/sk.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sl.rs b/src/lang/sl.rs
index 6b356a238..f4c5ff385 100755
--- a/src/lang/sl.rs
+++ b/src/lang/sl.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sq.rs b/src/lang/sq.rs
index 5eb5c0fb4..11e3e1ccb 100644
--- a/src/lang/sq.rs
+++ b/src/lang/sq.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sr.rs b/src/lang/sr.rs
index f642bc124..494999475 100644
--- a/src/lang/sr.rs
+++ b/src/lang/sr.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sv.rs b/src/lang/sv.rs
index 76ea47cd4..4c0f73f5a 100644
--- a/src/lang/sv.rs
+++ b/src/lang/sv.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/template.rs b/src/lang/template.rs
index 06591d147..ee7fb0d46 100644
--- a/src/lang/template.rs
+++ b/src/lang/template.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/th.rs b/src/lang/th.rs
index 6e21420fa..e6f12d85e 100644
--- a/src/lang/th.rs
+++ b/src/lang/th.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/tr.rs b/src/lang/tr.rs
index 15aaac5f7..bb3ab5de6 100644
--- a/src/lang/tr.rs
+++ b/src/lang/tr.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/tw.rs b/src/lang/tw.rs
index 6d9d8089c..8f28395d3 100644
--- a/src/lang/tw.rs
+++ b/src/lang/tw.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "未成功獲取地址簿"),
("push_ab_failed_tip", "未成功上傳地址簿"),
("synced_peer_readded_tip", "最近會話中存在的設備將會被重新同步到地址簿。"),
+ ("Change Color", "更改顏色"),
].iter().cloned().collect();
}
diff --git a/src/lang/ua.rs b/src/lang/ua.rs
index acdf8f106..69ca7c2da 100644
--- a/src/lang/ua.rs
+++ b/src/lang/ua.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/vn.rs b/src/lang/vn.rs
index 8aeafd930..7a0cce355 100644
--- a/src/lang/vn.rs
+++ b/src/lang/vn.rs
@@ -538,5 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", ""),
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
+ ("Change Color", ""),
].iter().cloned().collect();
}
From 7f7d5d9f4c9cf8e3eb91116663fbf250c298acab Mon Sep 17 00:00:00 2001
From: dignow
Date: Tue, 22 Aug 2023 21:52:23 +0800
Subject: [PATCH 37/75] oidc, add default gitlab icon
Signed-off-by: dignow
---
flutter/assets/auth-gitlab.svg | 1 +
flutter/lib/common/widgets/login.dart | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
create mode 100644 flutter/assets/auth-gitlab.svg
diff --git a/flutter/assets/auth-gitlab.svg b/flutter/assets/auth-gitlab.svg
new file mode 100644
index 000000000..c4ec9d2ec
--- /dev/null
+++ b/flutter/assets/auth-gitlab.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/flutter/lib/common/widgets/login.dart b/flutter/lib/common/widgets/login.dart
index 7c17e9dea..b26397b94 100644
--- a/flutter/lib/common/widgets/login.dart
+++ b/flutter/lib/common/widgets/login.dart
@@ -14,6 +14,7 @@ import './dialog.dart';
const kOpSvgList = [
'github',
+ 'gitlab',
'google',
'apple',
'okta',
@@ -72,6 +73,11 @@ class ButtonOP extends StatelessWidget {
@override
Widget build(BuildContext context) {
+ final opLabel = {
+ 'github': 'GitHub',
+ 'gitlab': 'GitLab'
+ }[op.toLowerCase()] ??
+ toCapitalized(op);
return Row(children: [
Container(
height: height,
@@ -97,8 +103,7 @@ class ButtonOP extends StatelessWidget {
child: FittedBox(
fit: BoxFit.scaleDown,
child: Center(
- child: Text(
- '${translate("Continue with")} ${op.toLowerCase() == "github" ? "GitHub" : toCapitalized(op)}')),
+ child: Text('${translate("Continue with")} $opLabel')),
),
),
],
From 6666dece5d58e93b83c25530d9b9d8070dc135d3 Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Tue, 22 Aug 2023 22:02:42 +0800
Subject: [PATCH 38/75] svgo gitlab.svg
---
flutter/assets/auth-gitlab.svg | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flutter/assets/auth-gitlab.svg b/flutter/assets/auth-gitlab.svg
index c4ec9d2ec..9402e1329 100644
--- a/flutter/assets/auth-gitlab.svg
+++ b/flutter/assets/auth-gitlab.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
From 9cb778618209b6f43a9cf94fea7500aa39648578 Mon Sep 17 00:00:00 2001
From: SergeyMy <131688106+SergeyMy@users.noreply.github.com>
Date: Tue, 22 Aug 2023 19:26:59 +0500
Subject: [PATCH 39/75] Update ru.rs
---
src/lang/ru.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lang/ru.rs b/src/lang/ru.rs
index 37fdb2060..74192a872 100644
--- a/src/lang/ru.rs
+++ b/src/lang/ru.rs
@@ -538,6 +538,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Невозможно обновить адресную книгу"),
("push_ab_failed_tip", "Невозможно синхронизировать адресную книгу с сервером"),
("synced_peer_readded_tip", "Устройства, присутствовавшие в последних сеансах, будут синхронизированы с адресной книгой."),
- ("Change Color", ""),
+ ("Change Color", "Изменить цвет"),
].iter().cloned().collect();
}
From 8427b03a394ff5f9f372ee224b10d697052c6737 Mon Sep 17 00:00:00 2001
From: Sahil Yeole
Date: Wed, 23 Aug 2023 00:13:23 +0530
Subject: [PATCH 40/75] Using github latest release url to check for software
update
Signed-off-by: Sahil Yeole
---
src/common.rs | 33 +++++++++++----------------------
1 file changed, 11 insertions(+), 22 deletions(-)
diff --git a/src/common.rs b/src/common.rs
index 011ca0524..5ad92d914 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -831,30 +831,19 @@ pub fn check_software_update() {
#[tokio::main(flavor = "current_thread")]
async fn check_software_update_() -> hbb_common::ResultType<()> {
- sleep(3.).await;
+ let url = "https://github.com/rustdesk/rustdesk/releases/latest";
+ let latest_release_response = reqwest::get(url).await?;
+ let latest_release_version = latest_release_response
+ .url()
+ .path()
+ .rsplit('/')
+ .next()
+ .unwrap();
- let rendezvous_server = format!("rs-sg.rustdesk.com:{}", config::RENDEZVOUS_PORT);
- let (mut socket, rendezvous_server) =
- socket_client::new_udp_for(&rendezvous_server, CONNECT_TIMEOUT).await?;
+ let response_url = latest_release_response.url().to_string();
- let mut msg_out = RendezvousMessage::new();
- msg_out.set_software_update(SoftwareUpdate {
- url: crate::VERSION.to_owned(),
- ..Default::default()
- });
- socket.send(&msg_out, rendezvous_server).await?;
- use hbb_common::protobuf::Message;
- for _ in 0..2 {
- if let Some(Ok((bytes, _))) = socket.next_timeout(READ_TIMEOUT).await {
- if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
- if let Some(rendezvous_message::Union::SoftwareUpdate(su)) = msg_in.union {
- let version = hbb_common::get_version_from_url(&su.url);
- if get_version_number(&version) > get_version_number(crate::VERSION) {
- *SOFTWARE_UPDATE_URL.lock().unwrap() = su.url;
- }
- }
- }
- }
+ if get_version_number(&latest_release_version) > get_version_number(crate::VERSION) {
+ *SOFTWARE_UPDATE_URL.lock().unwrap() = response_url;
}
Ok(())
}
From f41cb0d81c67844786892dd32a28c029a4b0e990 Mon Sep 17 00:00:00 2001
From: Sahil Yeole
Date: Wed, 23 Aug 2023 00:14:32 +0530
Subject: [PATCH 41/75] updated get_new_version for ui
Signed-off-by: Sahil Yeole
---
src/ui_interface.rs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/ui_interface.rs b/src/ui_interface.rs
index 7e1b3a9bb..6c0d38354 100644
--- a/src/ui_interface.rs
+++ b/src/ui_interface.rs
@@ -594,7 +594,8 @@ pub fn current_is_wayland() -> bool {
#[inline]
pub fn get_new_version() -> String {
- hbb_common::get_version_from_url(&*SOFTWARE_UPDATE_URL.lock().unwrap())
+ // hbb_common::get_version_from_url(&*SOFTWARE_UPDATE_URL.lock().unwrap())
+ (*SOFTWARE_UPDATE_URL.lock().unwrap().rsplit('/').next().unwrap_or("")).to_string()
}
#[inline]
From d87ea854bc380b6307a9cc2572026ec5024d755b Mon Sep 17 00:00:00 2001
From: 21pages
Date: Wed, 23 Aug 2023 08:15:56 +0800
Subject: [PATCH 42/75] add ColorPicker translations
Signed-off-by: 21pages
---
flutter/lib/common/widgets/address_book.dart | 7 +++++++
flutter/lib/common/widgets/peer_card.dart | 5 +++--
src/lang/ca.rs | 2 ++
src/lang/cn.rs | 2 ++
src/lang/cs.rs | 2 ++
src/lang/da.rs | 2 ++
src/lang/de.rs | 2 ++
src/lang/el.rs | 2 ++
src/lang/eo.rs | 2 ++
src/lang/es.rs | 2 ++
src/lang/fa.rs | 2 ++
src/lang/fr.rs | 2 ++
src/lang/hu.rs | 2 ++
src/lang/id.rs | 2 ++
src/lang/it.rs | 2 ++
src/lang/ja.rs | 2 ++
src/lang/ko.rs | 2 ++
src/lang/kz.rs | 2 ++
src/lang/lt.rs | 2 ++
src/lang/nl.rs | 2 ++
src/lang/pl.rs | 2 ++
src/lang/pt_PT.rs | 2 ++
src/lang/ptbr.rs | 2 ++
src/lang/ro.rs | 2 ++
src/lang/ru.rs | 2 ++
src/lang/sk.rs | 2 ++
src/lang/sl.rs | 2 ++
src/lang/sq.rs | 2 ++
src/lang/sr.rs | 2 ++
src/lang/sv.rs | 2 ++
src/lang/template.rs | 2 ++
src/lang/th.rs | 2 ++
src/lang/tr.rs | 2 ++
src/lang/tw.rs | 2 ++
src/lang/ua.rs | 2 ++
src/lang/vn.rs | 2 ++
36 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/flutter/lib/common/widgets/address_book.dart b/flutter/lib/common/widgets/address_book.dart
index 292266ae7..4af74e319 100644
--- a/flutter/lib/common/widgets/address_book.dart
+++ b/flutter/lib/common/widgets/address_book.dart
@@ -579,6 +579,13 @@ class AddressBookTag extends StatelessWidget {
ColorPickerType.accent: false,
ColorPickerType.wheel: true,
},
+ pickerTypeLabels: {
+ ColorPickerType.primary: translate("Primary Color"),
+ ColorPickerType.wheel: translate("HSV Color"),
+ },
+ actionButtons: ColorPickerActionButtons(
+ dialogOkButtonLabel: translate("OK"),
+ dialogCancelButtonLabel: translate("Cancel")),
showColorCode: true,
);
if (oldColor != newColor) {
diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart
index 74f0dcb31..a9d18b42c 100644
--- a/flutter/lib/common/widgets/peer_card.dart
+++ b/flutter/lib/common/widgets/peer_card.dart
@@ -735,11 +735,12 @@ abstract class BasePeerCard extends StatelessWidget {
proc: () async {
bool result = gFFI.abModel.changePassword(id, '');
await bind.mainForgetPassword(id: id);
+ bool toast = false;
if (result) {
- bool toast = tab == PeerTabIndex.ab;
+ toast = tab == PeerTabIndex.ab;
gFFI.abModel.pushAb(toastIfFail: toast, toastIfSucc: toast);
}
- showToast(translate('Successful'));
+ if (!toast) showToast(translate('Successful'));
},
padding: menuPadding,
dismissOnClicked: true,
diff --git a/src/lang/ca.rs b/src/lang/ca.rs
index 4801abcae..baf6992b9 100644
--- a/src/lang/ca.rs
+++ b/src/lang/ca.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/cn.rs b/src/lang/cn.rs
index 3313537d1..8c20966c0 100644
--- a/src/lang/cn.rs
+++ b/src/lang/cn.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "未成功上传地址簿"),
("synced_peer_readded_tip", "最近会话中存在的设备将会被重新同步到地址簿。"),
("Change Color", "更改颜色"),
+ ("Primary Color", "基本色"),
+ ("HSV Color", "HSV 色"),
].iter().cloned().collect();
}
diff --git a/src/lang/cs.rs b/src/lang/cs.rs
index 3d913b0d6..0e4d4db65 100644
--- a/src/lang/cs.rs
+++ b/src/lang/cs.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "Nepodařilo se synchronizovat adresář se serverem"),
("synced_peer_readded_tip", "Zařízení, která byla přítomna v posledních relacích, budou synchronizována zpět do adresáře."),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/da.rs b/src/lang/da.rs
index afaf98386..c5540e75e 100644
--- a/src/lang/da.rs
+++ b/src/lang/da.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/de.rs b/src/lang/de.rs
index 8eb066f30..c528acceb 100644
--- a/src/lang/de.rs
+++ b/src/lang/de.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "Synchronisierung des Adressbuchs mit dem Server fehlgeschlagen"),
("synced_peer_readded_tip", "Die Geräte, die in den letzten Sitzungen vorhanden waren, werden erneut zum Adressbuch hinzugefügt."),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/el.rs b/src/lang/el.rs
index 56805e574..4e065c803 100644
--- a/src/lang/el.rs
+++ b/src/lang/el.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/eo.rs b/src/lang/eo.rs
index bcb467839..c77126729 100644
--- a/src/lang/eo.rs
+++ b/src/lang/eo.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/es.rs b/src/lang/es.rs
index 5384dfead..7bb24ac53 100644
--- a/src/lang/es.rs
+++ b/src/lang/es.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "No se ha podido sincronizar el directorio con el servidor"),
("synced_peer_readded_tip", "Los dispositivos presentes en sesiones recientes se sincronizarán con el directorio."),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/fa.rs b/src/lang/fa.rs
index fab82f661..35207642a 100644
--- a/src/lang/fa.rs
+++ b/src/lang/fa.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/fr.rs b/src/lang/fr.rs
index 24cc268ee..f9263d572 100644
--- a/src/lang/fr.rs
+++ b/src/lang/fr.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "Échec de la synchronisation du carnet d'adresses"),
("synced_peer_readded_tip", "Les appareils qui étaient présents dans les sessions récentes seront synchronisés avec le carnet d'adresses."),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/hu.rs b/src/lang/hu.rs
index aaf888d23..722011788 100644
--- a/src/lang/hu.rs
+++ b/src/lang/hu.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/id.rs b/src/lang/id.rs
index a7b12f2ed..c8c343c5b 100644
--- a/src/lang/id.rs
+++ b/src/lang/id.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "Gagal menyinkronkan buku alamat ke server"),
("synced_peer_readded_tip", "Perangkat yang terdaftar dalam sesi-sesi terbaru akan di-sinkronkan kembali ke buku alamat."),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/it.rs b/src/lang/it.rs
index 3b8bd8416..22088a061 100644
--- a/src/lang/it.rs
+++ b/src/lang/it.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "Impossibile sincronizzare la rubrica con il server"),
("synced_peer_readded_tip", "I dispositivi presenti nelle sessioni recenti saranno sincronizzati di nuovo nella rubrica."),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ja.rs b/src/lang/ja.rs
index 1a9e8da4f..b1da5d94c 100644
--- a/src/lang/ja.rs
+++ b/src/lang/ja.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ko.rs b/src/lang/ko.rs
index 28c34f7e2..a69b38e26 100644
--- a/src/lang/ko.rs
+++ b/src/lang/ko.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/kz.rs b/src/lang/kz.rs
index 2fb2b8b92..ccca49561 100644
--- a/src/lang/kz.rs
+++ b/src/lang/kz.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/lt.rs b/src/lang/lt.rs
index 6a8c7e9f5..873f5909a 100644
--- a/src/lang/lt.rs
+++ b/src/lang/lt.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/nl.rs b/src/lang/nl.rs
index 3b08427df..2be2d5da2 100644
--- a/src/lang/nl.rs
+++ b/src/lang/nl.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/pl.rs b/src/lang/pl.rs
index 67b9d188a..0391dd2f3 100644
--- a/src/lang/pl.rs
+++ b/src/lang/pl.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs
index 416600eeb..becb4c8ee 100644
--- a/src/lang/pt_PT.rs
+++ b/src/lang/pt_PT.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs
index 98e469f7e..704b56d1e 100644
--- a/src/lang/ptbr.rs
+++ b/src/lang/ptbr.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ro.rs b/src/lang/ro.rs
index f4d44b3ae..2f248262b 100644
--- a/src/lang/ro.rs
+++ b/src/lang/ro.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/ru.rs b/src/lang/ru.rs
index 37fdb2060..1c43912c6 100644
--- a/src/lang/ru.rs
+++ b/src/lang/ru.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "Невозможно синхронизировать адресную книгу с сервером"),
("synced_peer_readded_tip", "Устройства, присутствовавшие в последних сеансах, будут синхронизированы с адресной книгой."),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sk.rs b/src/lang/sk.rs
index 8421bd2b0..9711586d3 100644
--- a/src/lang/sk.rs
+++ b/src/lang/sk.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sl.rs b/src/lang/sl.rs
index f4c5ff385..f5f4f95f2 100755
--- a/src/lang/sl.rs
+++ b/src/lang/sl.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sq.rs b/src/lang/sq.rs
index 11e3e1ccb..e5d310ebb 100644
--- a/src/lang/sq.rs
+++ b/src/lang/sq.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sr.rs b/src/lang/sr.rs
index 494999475..480964e6e 100644
--- a/src/lang/sr.rs
+++ b/src/lang/sr.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/sv.rs b/src/lang/sv.rs
index 4c0f73f5a..cf94e7064 100644
--- a/src/lang/sv.rs
+++ b/src/lang/sv.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/template.rs b/src/lang/template.rs
index ee7fb0d46..c71a30342 100644
--- a/src/lang/template.rs
+++ b/src/lang/template.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/th.rs b/src/lang/th.rs
index e6f12d85e..1ec47d26c 100644
--- a/src/lang/th.rs
+++ b/src/lang/th.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/tr.rs b/src/lang/tr.rs
index bb3ab5de6..3c3a10da2 100644
--- a/src/lang/tr.rs
+++ b/src/lang/tr.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/tw.rs b/src/lang/tw.rs
index 8f28395d3..8ef8ca895 100644
--- a/src/lang/tw.rs
+++ b/src/lang/tw.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "未成功上傳地址簿"),
("synced_peer_readded_tip", "最近會話中存在的設備將會被重新同步到地址簿。"),
("Change Color", "更改顏色"),
+ ("Primary Color", "基本色"),
+ ("HSV Color", "HSV 色"),
].iter().cloned().collect();
}
diff --git a/src/lang/ua.rs b/src/lang/ua.rs
index 69ca7c2da..6be8c93b2 100644
--- a/src/lang/ua.rs
+++ b/src/lang/ua.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
diff --git a/src/lang/vn.rs b/src/lang/vn.rs
index 7a0cce355..d83d9ef42 100644
--- a/src/lang/vn.rs
+++ b/src/lang/vn.rs
@@ -539,5 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", ""),
("synced_peer_readded_tip", ""),
("Change Color", ""),
+ ("Primary Color", ""),
+ ("HSV Color", ""),
].iter().cloned().collect();
}
From f4d120b11f4d9e5c831473f4657c5c8adfe4abaa Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Wed, 23 Aug 2023 12:04:19 +0800
Subject: [PATCH 43/75] remove useless line
---
src/ui_interface.rs | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/ui_interface.rs b/src/ui_interface.rs
index 6c0d38354..ed2b4f4fc 100644
--- a/src/ui_interface.rs
+++ b/src/ui_interface.rs
@@ -594,7 +594,6 @@ pub fn current_is_wayland() -> bool {
#[inline]
pub fn get_new_version() -> String {
- // hbb_common::get_version_from_url(&*SOFTWARE_UPDATE_URL.lock().unwrap())
(*SOFTWARE_UPDATE_URL.lock().unwrap().rsplit('/').next().unwrap_or("")).to_string()
}
From da9fb46b6a65d9c96d15ac4c18cac8fa5be59a5e Mon Sep 17 00:00:00 2001
From: 21pages
Date: Wed, 23 Aug 2023 12:20:19 +0800
Subject: [PATCH 44/75] fix pushAb
Signed-off-by: 21pages
---
flutter/lib/models/ab_model.dart | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flutter/lib/models/ab_model.dart b/flutter/lib/models/ab_model.dart
index e91e42ef9..cbb7f7471 100644
--- a/flutter/lib/models/ab_model.dart
+++ b/flutter/lib/models/ab_model.dart
@@ -225,7 +225,7 @@ class AbModel {
final api = "${await bind.mainGetApiServer()}/api/ab";
var authHeaders = getHttpHeaders();
authHeaders['Content-Type'] = "application/json";
- final body = jsonEncode(_serialize());
+ final body = jsonEncode({"data": jsonEncode(_serialize())});
http.Response resp;
// support compression
if (licensedDevices > 0 && body.length > 1024) {
From 28c0e15058298afdbb5b3234266bca2905df7c3d Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Wed, 23 Aug 2023 12:56:33 +0800
Subject: [PATCH 45/75] bump to 1.2.3
---
.github/workflows/flutter-build.yml | 2 +-
.github/workflows/flutter-tag.yml | 2 +-
.github/workflows/history.yml | 2 +-
Cargo.lock | 2 +-
Cargo.toml | 2 +-
appimage/AppImageBuilder-aarch64.yml | 4 ++--
appimage/AppImageBuilder-x86_64.yml | 4 ++--
flatpak/rustdesk.json | 4 ++--
flutter/pubspec.yaml | 2 +-
res/PKGBUILD | 2 +-
res/rpm-flutter-suse.spec | 2 +-
res/rpm-flutter.spec | 2 +-
res/rpm.spec | 2 +-
13 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml
index 3ccf4988a..69f7df67b 100644
--- a/.github/workflows/flutter-build.yml
+++ b/.github/workflows/flutter-build.yml
@@ -22,7 +22,7 @@ env:
# vcpkg version: 2023.04.15
# for multiarch gcc compatibility
VCPKG_COMMIT_ID: "501db0f17ef6df184fcdbfbe0f87cde2313b6ab1"
- VERSION: "1.2.2"
+ VERSION: "1.2.3"
NDK_VERSION: "r25c"
#signing keys env variable checks
ANDROID_SIGNING_KEY: '${{ secrets.ANDROID_SIGNING_KEY }}'
diff --git a/.github/workflows/flutter-tag.yml b/.github/workflows/flutter-tag.yml
index 56ec2c43e..4925f26c8 100644
--- a/.github/workflows/flutter-tag.yml
+++ b/.github/workflows/flutter-tag.yml
@@ -15,4 +15,4 @@ jobs:
secrets: inherit
with:
upload-artifact: true
- upload-tag: "1.2.2"
+ upload-tag: "1.2.3"
diff --git a/.github/workflows/history.yml b/.github/workflows/history.yml
index 6e276162a..6921ea4cd 100644
--- a/.github/workflows/history.yml
+++ b/.github/workflows/history.yml
@@ -10,7 +10,7 @@ env:
# vcpkg version: 2022.05.10
# for multiarch gcc compatibility
VCPKG_COMMIT_ID: "501db0f17ef6df184fcdbfbe0f87cde2313b6ab1"
- VERSION: "1.2.2"
+ VERSION: "1.2.3"
jobs:
build-for-history-windows:
diff --git a/Cargo.lock b/Cargo.lock
index 1dc94cfda..99784e400 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5124,7 +5124,7 @@ dependencies = [
[[package]]
name = "rustdesk"
-version = "1.2.2"
+version = "1.2.3"
dependencies = [
"android_logger",
"arboard",
diff --git a/Cargo.toml b/Cargo.toml
index f1e714e82..2abc198cd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "rustdesk"
-version = "1.2.2"
+version = "1.2.3"
authors = ["rustdesk "]
edition = "2021"
build= "build.rs"
diff --git a/appimage/AppImageBuilder-aarch64.yml b/appimage/AppImageBuilder-aarch64.yml
index b372f4eb9..337e022be 100644
--- a/appimage/AppImageBuilder-aarch64.yml
+++ b/appimage/AppImageBuilder-aarch64.yml
@@ -2,7 +2,7 @@
version: 1
script:
- rm -rf ./AppDir || true
- - bsdtar -zxvf ../rustdesk-1.2.2.deb
+ - bsdtar -zxvf ../rustdesk-1.2.3.deb
- tar -xvf ./data.tar.xz
- mkdir ./AppDir
- mv ./usr ./AppDir/usr
@@ -18,7 +18,7 @@ AppDir:
id: rustdesk
name: rustdesk
icon: rustdesk
- version: 1.2.2
+ version: 1.2.3
exec: usr/lib/rustdesk/rustdesk
exec_args: $@
apt:
diff --git a/appimage/AppImageBuilder-x86_64.yml b/appimage/AppImageBuilder-x86_64.yml
index 9a4054b62..650d2f201 100644
--- a/appimage/AppImageBuilder-x86_64.yml
+++ b/appimage/AppImageBuilder-x86_64.yml
@@ -2,7 +2,7 @@
version: 1
script:
- rm -rf ./AppDir || true
- - bsdtar -zxvf ../rustdesk-1.2.2.deb
+ - bsdtar -zxvf ../rustdesk-1.2.3.deb
- tar -xvf ./data.tar.xz
- mkdir ./AppDir
- mv ./usr ./AppDir/usr
@@ -18,7 +18,7 @@ AppDir:
id: rustdesk
name: rustdesk
icon: rustdesk
- version: 1.2.2
+ version: 1.2.3
exec: usr/lib/rustdesk/rustdesk
exec_args: $@
apt:
diff --git a/flatpak/rustdesk.json b/flatpak/rustdesk.json
index 4a8334fc9..4d2e297cc 100644
--- a/flatpak/rustdesk.json
+++ b/flatpak/rustdesk.json
@@ -12,7 +12,7 @@
"name": "rustdesk",
"buildsystem": "simple",
"build-commands": [
- "bsdtar -zxvf rustdesk-1.2.2.deb",
+ "bsdtar -zxvf rustdesk-1.2.3.deb",
"tar -xvf ./data.tar.xz",
"cp -r ./usr/* /app/",
"mkdir -p /app/bin && ln -s /app/lib/rustdesk/rustdesk /app/bin/rustdesk",
@@ -26,7 +26,7 @@
"sources": [
{
"type": "file",
- "path": "../rustdesk-1.2.2.deb"
+ "path": "../rustdesk-1.2.3.deb"
},
{
"type": "file",
diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml
index 04af8f92f..b7141455d 100644
--- a/flutter/pubspec.yaml
+++ b/flutter/pubspec.yaml
@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# 1.1.9-1 works for android, but for ios it becomes 1.1.91, need to set it to 1.1.9-a.1 for iOS, will get 1.1.9.1, but iOS store not allow 4 numbers
-version: 1.2.2
+version: 1.2.3
environment:
sdk: ">=2.17.0"
diff --git a/res/PKGBUILD b/res/PKGBUILD
index 4d3911b3b..0e83b6891 100644
--- a/res/PKGBUILD
+++ b/res/PKGBUILD
@@ -1,5 +1,5 @@
pkgname=rustdesk
-pkgver=1.2.2
+pkgver=1.2.3
pkgrel=0
epoch=
pkgdesc=""
diff --git a/res/rpm-flutter-suse.spec b/res/rpm-flutter-suse.spec
index 08080424c..8c71fa7de 100644
--- a/res/rpm-flutter-suse.spec
+++ b/res/rpm-flutter-suse.spec
@@ -1,5 +1,5 @@
Name: rustdesk
-Version: 1.2.2
+Version: 1.2.3
Release: 0
Summary: RPM package
License: GPL-3.0
diff --git a/res/rpm-flutter.spec b/res/rpm-flutter.spec
index 5b4899bff..ca63093eb 100644
--- a/res/rpm-flutter.spec
+++ b/res/rpm-flutter.spec
@@ -1,5 +1,5 @@
Name: rustdesk
-Version: 1.2.2
+Version: 1.2.3
Release: 0
Summary: RPM package
License: GPL-3.0
diff --git a/res/rpm.spec b/res/rpm.spec
index 6ce788ae7..c92ad904a 100644
--- a/res/rpm.spec
+++ b/res/rpm.spec
@@ -1,5 +1,5 @@
Name: rustdesk
-Version: 1.2.2
+Version: 1.2.3
Release: 0
Summary: RPM package
License: GPL-3.0
From 33cbed592a5821664541c5525b7409b6197291d1 Mon Sep 17 00:00:00 2001
From: SergeyMy <131688106+SergeyMy@users.noreply.github.com>
Date: Wed, 23 Aug 2023 12:25:43 +0500
Subject: [PATCH 46/75] Update ru.rs
---
src/lang/ru.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lang/ru.rs b/src/lang/ru.rs
index 69f4f2f19..cc5e97da8 100644
--- a/src/lang/ru.rs
+++ b/src/lang/ru.rs
@@ -539,7 +539,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("push_ab_failed_tip", "Невозможно синхронизировать адресную книгу с сервером"),
("synced_peer_readded_tip", "Устройства, присутствовавшие в последних сеансах, будут синхронизированы с адресной книгой."),
("Change Color", "Изменить цвет"),
- ("Primary Color", ""),
- ("HSV Color", ""),
+ ("Primary Color", "Основной цвет"),
+ ("HSV Color", "HSV цвет"),
].iter().cloned().collect();
}
From 8785c08861f602c9f33b5d6ded5c606e92f1fa68 Mon Sep 17 00:00:00 2001
From: Mr-Update <37781396+Mr-Update@users.noreply.github.com>
Date: Wed, 23 Aug 2023 14:27:30 +0200
Subject: [PATCH 47/75] Update de.rs
---
src/lang/de.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/lang/de.rs b/src/lang/de.rs
index c528acceb..fe1fe864f 100644
--- a/src/lang/de.rs
+++ b/src/lang/de.rs
@@ -538,8 +538,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Aktualisierung des Adressbuchs fehlgeschlagen"),
("push_ab_failed_tip", "Synchronisierung des Adressbuchs mit dem Server fehlgeschlagen"),
("synced_peer_readded_tip", "Die Geräte, die in den letzten Sitzungen vorhanden waren, werden erneut zum Adressbuch hinzugefügt."),
- ("Change Color", ""),
- ("Primary Color", ""),
- ("HSV Color", ""),
+ ("Change Color", "Farbe ändern"),
+ ("Primary Color", "Primärfarbe"),
+ ("HSV Color", "HSV-Farbe"),
].iter().cloned().collect();
}
From cb73490107c36f36625b70ae6291df7b56b4dcb7 Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Wed, 23 Aug 2023 21:59:22 +0800
Subject: [PATCH 48/75] add quick fix for
https://github.com/rustdesk/rustdesk/issues/5488#issuecomment-1689997785
---
flutter/lib/desktop/pages/remote_tab_page.dart | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart
index 51bcec51d..9c6ed6cec 100644
--- a/flutter/lib/desktop/pages/remote_tab_page.dart
+++ b/flutter/lib/desktop/pages/remote_tab_page.dart
@@ -354,7 +354,15 @@ class _ConnectionTabPageState extends State {
));
}
- if (perms['keyboard'] != false && !ffi.ffiModel.viewOnly) {}
+ if (perms['keyboard'] != false && !ffi.ffiModel.viewOnly) {
+ menu.add(RemoteMenuEntry.insertLock(sessionId, padding,
+ dismissFunc: cancelFunc));
+
+ if (pi.platform == kPeerPlatformLinux || pi.sasEnabled) {
+ menu.add(RemoteMenuEntry.insertCtrlAltDel(sessionId, padding,
+ dismissFunc: cancelFunc));
+ }
+ }
menu.addAll([
MenuEntryDivider(),
From dade589075da95c735058a7b0090b03d5859b8b0 Mon Sep 17 00:00:00 2001
From: fufesou
Date: Wed, 23 Aug 2023 23:29:15 +0800
Subject: [PATCH 49/75] fix, enable menu before image
Signed-off-by: fufesou
---
flutter/lib/desktop/pages/remote_page.dart | 84 ++++++++++++----------
src/client.rs | 3 +
src/common.rs | 2 +-
3 files changed, 52 insertions(+), 37 deletions(-)
diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart
index 0d51cabdd..8084b230d 100644
--- a/flutter/lib/desktop/pages/remote_page.dart
+++ b/flutter/lib/desktop/pages/remote_page.dart
@@ -228,49 +228,61 @@ class _RemotePageState extends State
removeSharedStates(widget.id);
}
+ Widget emptyOverlay() => GestureDetector(
+ behavior: HitTestBehavior.translucent,
+ onTap: () {
+ bind.sessionInputOsPassword(sessionId: sessionId, value: '');
+ },
+ child: BlockableOverlay(
+ state: _blockableOverlayState,
+ underlying: Container(
+ color: Colors.transparent,
+ ),
+ ),
+ );
+
Widget buildBody(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
/// the Overlay key will be set with _blockableOverlayState in BlockableOverlay
/// see override build() in [BlockableOverlay]
- body: BlockableOverlay(
- state: _blockableOverlayState,
- underlying: Container(
- color: Colors.black,
- child: RawKeyFocusScope(
- focusNode: _rawKeyFocusNode,
- onFocusChange: (bool imageFocused) {
- debugPrint(
- "onFocusChange(window active:${!_isWindowBlur}) $imageFocused");
- // See [onWindowBlur].
- if (Platform.isWindows) {
- if (_isWindowBlur) {
- imageFocused = false;
- Future.delayed(Duration.zero, () {
- _rawKeyFocusNode.unfocus();
- });
+ body: Stack(
+ children: [
+ Container(
+ color: Colors.black,
+ child: RawKeyFocusScope(
+ focusNode: _rawKeyFocusNode,
+ onFocusChange: (bool imageFocused) {
+ debugPrint(
+ "onFocusChange(window active:${!_isWindowBlur}) $imageFocused");
+ // See [onWindowBlur].
+ if (Platform.isWindows) {
+ if (_isWindowBlur) {
+ imageFocused = false;
+ Future.delayed(Duration.zero, () {
+ _rawKeyFocusNode.unfocus();
+ });
+ }
+ if (imageFocused) {
+ _ffi.inputModel.enterOrLeave(true);
+ } else {
+ _ffi.inputModel.enterOrLeave(false);
+ }
}
- if (imageFocused) {
- _ffi.inputModel.enterOrLeave(true);
- } else {
- _ffi.inputModel.enterOrLeave(false);
- }
- }
- },
- inputModel: _ffi.inputModel,
- child: getBodyForDesktop(context))),
- upperLayer: [
- OverlayEntry(
- builder: (context) => RemoteToolbar(
- id: widget.id,
- ffi: _ffi,
- state: widget.toolbarState,
- onEnterOrLeaveImageSetter: (func) =>
- _onEnterOrLeaveImage4Toolbar = func,
- onEnterOrLeaveImageCleaner: () =>
- _onEnterOrLeaveImage4Toolbar = null,
- ))
+ },
+ inputModel: _ffi.inputModel,
+ child: getBodyForDesktop(context))),
+ emptyOverlay(),
+ RemoteToolbar(
+ id: widget.id,
+ ffi: _ffi,
+ state: widget.toolbarState,
+ onEnterOrLeaveImageSetter: (func) =>
+ _onEnterOrLeaveImage4Toolbar = func,
+ onEnterOrLeaveImageCleaner: () =>
+ _onEnterOrLeaveImage4Toolbar = null,
+ ),
],
),
);
diff --git a/src/client.rs b/src/client.rs
index 9e3479da8..17a62ed54 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -2100,6 +2100,9 @@ fn _input_os_password(p: String, activate: bool, interface: impl Interface) {
activate_os(&interface);
std::thread::sleep(Duration::from_millis(1200));
}
+ if p.is_empty() {
+ return;
+ }
let mut key_event = KeyEvent::new();
key_event.press = true;
let mut msg_out = Message::new();
diff --git a/src/common.rs b/src/common.rs
index 5ad92d914..36ca972b2 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -25,7 +25,7 @@ use hbb_common::{
protobuf::Enum,
protobuf::Message as _,
rendezvous_proto::*,
- sleep, socket_client,
+ socket_client,
tcp::FramedStream,
tokio, ResultType,
};
From f2d96b895f1d29efa0eb3d2504c17f53c952ef7e Mon Sep 17 00:00:00 2001
From: fufesou
Date: Wed, 23 Aug 2023 23:57:09 +0800
Subject: [PATCH 50/75] hide empty waiting layer after images are reached
Signed-off-by: fufesou
---
flutter/lib/desktop/pages/remote_page.dart | 11 +++++++----
flutter/lib/models/model.dart | 19 ++++++++++---------
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart
index 8084b230d..339ecb3f2 100644
--- a/flutter/lib/desktop/pages/remote_page.dart
+++ b/flutter/lib/desktop/pages/remote_page.dart
@@ -234,6 +234,8 @@ class _RemotePageState extends State
bind.sessionInputOsPassword(sessionId: sessionId, value: '');
},
child: BlockableOverlay(
+ /// the Overlay key will be set with _blockableOverlayState in BlockableOverlay
+ /// see override build() in [BlockableOverlay]
state: _blockableOverlayState,
underlying: Container(
color: Colors.transparent,
@@ -244,9 +246,6 @@ class _RemotePageState extends State
Widget buildBody(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
-
- /// the Overlay key will be set with _blockableOverlayState in BlockableOverlay
- /// see override build() in [BlockableOverlay]
body: Stack(
children: [
Container(
@@ -273,7 +272,11 @@ class _RemotePageState extends State
},
inputModel: _ffi.inputModel,
child: getBodyForDesktop(context))),
- emptyOverlay(),
+ Obx(
+ () => _ffi.ffiModel.waitForFirstImage.isTrue
+ ? emptyOverlay()
+ : Offstage(),
+ ),
RemoteToolbar(
id: widget.id,
ffi: _ffi,
diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart
index 202216b59..25ba22c70 100644
--- a/flutter/lib/models/model.dart
+++ b/flutter/lib/models/model.dart
@@ -38,8 +38,6 @@ import 'platform_model.dart';
typedef HandleMsgBox = Function(Map evt, String id);
typedef ReconnectHandle = Function(OverlayDialogManager, SessionID, bool);
-final _waitForImageDialogShow = {};
-final _waitForFirstImage = {};
final _constSessionId = Uuid().v4obj();
class CachedPeerData {
@@ -100,6 +98,9 @@ class FfiModel with ChangeNotifier {
WeakReference parent;
late final SessionID sessionId;
+ RxBool waitForImageDialogShow = true.obs;
+ RxBool waitForFirstImage = true.obs;
+
Map get permissions => _permissions;
Display get display => _display;
@@ -498,7 +499,7 @@ class FfiModel with ChangeNotifier {
closeConnection();
}
- if (_waitForFirstImage[sessionId] == false) return;
+ if (waitForFirstImage.isFalse) return;
dialogManager.show(
(setState, close, context) => CustomAlertDialog(
title: null,
@@ -509,7 +510,7 @@ class FfiModel with ChangeNotifier {
onCancel: onClose),
tag: '$sessionId-waiting-for-image',
);
- _waitForImageDialogShow[sessionId] = true;
+ waitForImageDialogShow.value = true;
bind.sessionOnWaitingForImageDialogShow(sessionId: sessionId);
}
@@ -578,7 +579,7 @@ class FfiModel with ChangeNotifier {
}
if (displays.isNotEmpty) {
_reconnects = 1;
- _waitForFirstImage[sessionId] = true;
+ waitForFirstImage.value = true;
}
Map features = json.decode(evt['features']);
_pi.features.privacyMode = features['privacy_mode'] == 1;
@@ -1814,12 +1815,12 @@ class FFI {
}
void onEvent2UIRgba() async {
- if (_waitForImageDialogShow[sessionId] == true) {
- _waitForImageDialogShow[sessionId] = false;
+ if (ffiModel.waitForImageDialogShow.isTrue) {
+ ffiModel.waitForImageDialogShow.value = false;
clearWaitingForImage(dialogManager, sessionId);
}
- if (_waitForFirstImage[sessionId] == true) {
- _waitForFirstImage[sessionId] = false;
+ if (ffiModel.waitForFirstImage.value == true) {
+ ffiModel.waitForFirstImage.value = false;
dialogManager.dismissAll();
await canvasModel.updateViewStyle();
await canvasModel.updateScrollStyle();
From e17002c6da0b69fb93a80f4ae9153cc409f82a32 Mon Sep 17 00:00:00 2001
From: fufesou
Date: Thu, 24 Aug 2023 00:00:18 +0800
Subject: [PATCH 51/75] set right menu duration from 4s to 300s
Signed-off-by: fufesou
---
flutter/lib/desktop/widgets/tabbar_widget.dart | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart
index 0eb59f51b..148135a81 100644
--- a/flutter/lib/desktop/widgets/tabbar_widget.dart
+++ b/flutter/lib/desktop/widgets/tabbar_widget.dart
@@ -77,7 +77,7 @@ CancelFunc showRightMenu(ToastBuilder builder,
targetContext: context,
verticalOffset: 0,
horizontalOffset: 0,
- duration: Duration(seconds: 4),
+ duration: Duration(seconds: 300),
animationDuration: Duration(milliseconds: 0),
animationReverseDuration: Duration(milliseconds: 0),
preferDirection: PreferDirection.rightTop,
From 256f33b720d8685424ce574f018f821be342c14c Mon Sep 17 00:00:00 2001
From: Peter Dave Hello
Date: Tue, 22 Aug 2023 07:26:06 +0800
Subject: [PATCH 52/75] Update and improve tw translation
---
src/lang/tw.rs | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/lang/tw.rs b/src/lang/tw.rs
index 8ef8ca895..d5a6c6b83 100644
--- a/src/lang/tw.rs
+++ b/src/lang/tw.rs
@@ -528,16 +528,16 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Move tab to new window", "移動標籤到新視窗"),
("Can not be empty", "不能為空"),
("Already exists", "已經存在"),
- ("Change Password", ""),
- ("Refresh Password", ""),
- ("ID", ""),
- ("Grid View", ""),
- ("List View", ""),
- ("Select", ""),
- ("Toggle Tags", ""),
- ("pull_ab_failed_tip", "未成功獲取地址簿"),
- ("push_ab_failed_tip", "未成功上傳地址簿"),
- ("synced_peer_readded_tip", "最近會話中存在的設備將會被重新同步到地址簿。"),
+ ("Change Password", "更改密碼"),
+ ("Refresh Password", "重新整理密碼"),
+ ("ID", "ID"),
+ ("Grid View", "網格檢視"),
+ ("List View", "清單檢視"),
+ ("Select", "選擇"),
+ ("Toggle Tags", "切換標籤"),
+ ("pull_ab_failed_tip", "通訊錄更新失敗"),
+ ("push_ab_failed_tip", "成功同步通訊錄至伺服器"),
+ ("synced_peer_readded_tip", "最近會話中存在的設備將會被重新同步到通訊錄。"),
("Change Color", "更改顏色"),
("Primary Color", "基本色"),
("HSV Color", "HSV 色"),
From a7ef3ce58ae66c02ae75613404c723dcfc7f1ef3 Mon Sep 17 00:00:00 2001
From: Ibnul Mutaki
Date: Thu, 24 Aug 2023 08:01:41 +0700
Subject: [PATCH 53/75] fix some translate read me for indonesian translate,
add create contributing-id.md
---
docs/CONTRIBUTING-ID.md | 31 +++++++++++++++++++++++++++++++
docs/README-ID.md | 10 +++++-----
2 files changed, 36 insertions(+), 5 deletions(-)
create mode 100644 docs/CONTRIBUTING-ID.md
diff --git a/docs/CONTRIBUTING-ID.md b/docs/CONTRIBUTING-ID.md
new file mode 100644
index 000000000..cdff6c01f
--- /dev/null
+++ b/docs/CONTRIBUTING-ID.md
@@ -0,0 +1,31 @@
+# Berkontribusi dalam pengembangan RustDesk
+
+RustDesk mengajak semua orang untuk ikut berkontribusi. Berikut ini adalah panduan jika kamu sedang mempertimbangkan untuk memberikan bantuan kepada kami:
+
+## Kontirbusi
+
+Untuk melakukan kontribusi pada RustDesk atau dependensinya, sebaiknya dilakukan dalam bentuk pull request di GitHub. Setiap permintaan pull request akan ditinjau oleh kontributor utama atau seseorang yang memiliki wewenang untuk menggabungkan perubahan kode, baik yang sudah dimasukkan ke dalam struktur utama ataupun memberikan umpan balik untuk perubahan yang akan diperlukan. Setiap kontribusi harus sesuai dengan format ini, juga termasuk yang berasal dari kontributor utama.
+
+Apabila kamu ingin mengatasi sebuah masalah yang sudah ada di daftar issue, harap klaim terlebih dahulu dengan memberikan komentar pada GitHub issue yang ingin kamu kerjakan. Hal ini dilakukan untuk mencegah terjadinya duplikasi dari kontributor pada daftar issue yang sama.
+
+## Pemeriksaan Pull Request
+
+- Branch yang menjadi acuan adalah branch master dari repositori utama dan, jika diperlukan, lakukan rebase ke branch master yang terbaru sebelum kamu mengirim pull request. Apabila terdapat masalah kita melakukan proses merge ke branch master kemungkinan kamu akan diminta untuk melakukan rebase pada perubahan yang sudah dibuat.
+
+- Sebaiknya buatlah commit seminimal mungkin, sambil memastikan bahwa setiap commit yang dibuat sudah benar (contohnya, setiap commit harus bisa di kompilasi dan berhasil melewati tahap test).
+
+- Setiap commit harus disertai dengan tanda tangan Sertifikat Asal Pengembang (Developer Certificate of Origin) (), yang mengindikasikan bahwa kamu (and your employer if applicable) bersedia untuk patuh terhadap persyaratan dari [lisensi projek](../LICENCE). Di git bash, ini adalah opsi parameter `-s` pada `git commit`
+
+- Jika perubahan yang kamu buat tidak mendapat tinjauan atau kamu membutuhkan orang tertentu untuk meninjaunya, kamu bisa @-reply seorang reviewer meminta peninjauan dalam permintaan pull request atau komentar, atau kamu bisa meminta tinjauan melalui [email](mailto:info@rustdesk.com).
+
+- Sertakan test yang relevan terhadap bug atau fitur baru yang sudah dikerjakan.
+
+Untuk instruksi Git yang lebih lanjut, cek disini [GitHub workflow 101](https://github.com/servo/servo/wiki/GitHub-workflow).
+
+## Tindakan
+
+
+
+## Komunikasi
+
+Kontributor RustDesk sering berkunjung ke [Discord](https://discord.gg/nDceKgxnkV).
diff --git a/docs/README-ID.md b/docs/README-ID.md
index e4cb5560c..78aac233a 100644
--- a/docs/README-ID.md
+++ b/docs/README-ID.md
@@ -13,15 +13,15 @@ Mari mengobrol bersama kami: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter
[](https://ko-fi.com/I2I04VU09)
-Merupakan perangkat lunak Remote Desktop yang baru, dibangun dengan Rust. kamu bisa langsung menggunakannya tanpa perlu konfigurasi tambahan. Serta ,emiliki kontrol penuh terhadap semua data, tanpa perlu merasa was-was tentang isu keamanan, dan yang lebih menarik adalah memiliki opsi untuk menggunakan server rendezvous/relay milik kami, [konfigurasi server sendiri](https://rustdesk.com/server), atau [tulis rendezvous/relay server anda sendiri](https://github.com/rustdesk/rustdesk-server-demo).
+Merupakan perangkat lunak Remote Desktop yang baru, dan dibangun dengan Rust. Bahkan kamu bisa langsung menggunakannya tanpa perlu melakukan konfigurasi tambahan. Serta memiliki kontrol penuh terhadap semua data, tanpa perlu merasa was-was tentang isu keamanan, dan yang lebih menarik adalah memiliki opsi untuk menggunakan server rendezvous/relay milik kami, [konfigurasi server sendiri](https://rustdesk.com/server), atau [tulis rendezvous/relay server anda sendiri](https://github.com/rustdesk/rustdesk-server-demo).
-RustDesk mengajak semua orang untuk ikut berkontribusi. Lihat [`docs/CONTRIBUTING.md`](CONTRIBUTING.md) untuk melihat panduan.
+RustDesk mengajak semua orang untuk ikut berkontribusi. Lihat [`docs/CONTRIBUTING-ID.md`](CONTRIBUTING-ID.md) untuk melihat panduan.
[**UNDUH BINARY**](https://github.com/rustdesk/rustdesk/releases)
## Server Publik Gratis
-Di bawah ini merupakan server gratis yang bisa kamu gunakan, seiring waktu kemungkinan akan terjadi perubahan spesifikasi pada setiap server. Jika lokasi kamu berada jauh dengan salah satu server yang tersedia, kemungkinan koneksi akan terasa lambat ketika melakukan proses remote.
+Di bawah ini merupakan server gratis yang bisa kamu gunakan, seiring dengan waktu mungkin akan terjadi perubahan spesifikasi pada setiap server yang ada. Jika lokasi kamu berada jauh dengan salah satu server yang tersedia, kemungkinan koneksi akan terasa lambat ketika melakukan proses remote.
| Lokasi | Penyedia | Spesifikasi |
| --------- | ------------- | ------------------ |
| Jerman | [Hetzner](https://www.hetzner.com) | 2 vCPU / 4GB RAM |
@@ -31,11 +31,11 @@ Di bawah ini merupakan server gratis yang bisa kamu gunakan, seiring waktu kemun
[](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/rustdesk/rustdesk)
-Apabila kamu sudah menginstall VS Code dan Docker, kamu bisa mengklik badge yang ada diatas untuk memulainya. Dengan mengklik badge tersebut secara otomatis akan menginstal ekstensi pada VS Code, lakukan kloning (clone) source code kedalam container volume, dan aktifkan dev container untuk menggunakannya.
+Apabila PC kamu sudah terinstal VS Code dan Docker, kamu bisa mengklik badge yang ada diatas untuk memulainya. Dengan mengklik badge tersebut secara otomatis akan menginstal ekstensi pada VS Code, lakukan kloning (clone) source code kedalam container volume, dan aktifkan dev container untuk menggunakannya.
## Dependensi
-Pada versi desktop, antarmuka pengguna (GUI) menggunakan [Sciter](https://sciter.com/) atau flutter, tutorial ini hanya berlaku untuk Sciter
+Pada versi desktop, antarmuka pengguna (GUI) menggunakan [Sciter](https://sciter.com/) atau flutter
Kamu bisa mengunduh Sciter dynamic library disini.
From 88d0460e3c775a4c07b0c2f60e5b8e52ca1af988 Mon Sep 17 00:00:00 2001
From: 21pages
Date: Thu, 24 Aug 2023 10:04:34 +0800
Subject: [PATCH 54/75] alarm audit more info
Signed-off-by: 21pages
---
src/server/connection.rs | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/server/connection.rs b/src/server/connection.rs
index e982e6a93..4ab62cce3 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -1455,17 +1455,21 @@ impl Connection {
self.send_login_error("Too many wrong password attempts")
.await;
Self::post_alarm_audit(
- AlarmAuditType::ManyWrongPassword,
+ AlarmAuditType::ExceedThirtyAttempts,
json!({
"ip":self.ip,
+ "id":lr.my_id.clone(),
+ "name": lr.my_name.clone(),
}),
);
} else if time == failure.0 && failure.1 > 6 {
self.send_login_error("Please try 1 minute later").await;
Self::post_alarm_audit(
- AlarmAuditType::FrequentAttempt,
+ AlarmAuditType::SixAttemptsWithinOneMinute,
json!({
"ip":self.ip,
+ "id":lr.my_id.clone(),
+ "name": lr.my_name.clone(),
}),
);
} else if !self.validate_password() {
@@ -2504,8 +2508,8 @@ mod privacy_mode {
pub enum AlarmAuditType {
IpWhitelist = 0,
- ManyWrongPassword = 1,
- FrequentAttempt = 2,
+ ExceedThirtyAttempts = 1,
+ SixAttemptsWithinOneMinute = 2,
}
pub enum FileAuditType {
From 0e838d59d5cba5ba533b7fd4a9d7acebc0957f69 Mon Sep 17 00:00:00 2001
From: fufesou
Date: Thu, 24 Aug 2023 12:03:29 +0800
Subject: [PATCH 55/75] Check if peer info is set
Signed-off-by: fufesou
---
flutter/lib/desktop/pages/remote_page.dart | 24 ++++++++---------
.../lib/desktop/pages/remote_tab_page.dart | 7 ++++-
flutter/lib/models/model.dart | 13 +++++++++-
src/client.rs | 26 ++++++++++++++-----
4 files changed, 48 insertions(+), 22 deletions(-)
diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart
index 339ecb3f2..f8151e059 100644
--- a/flutter/lib/desktop/pages/remote_page.dart
+++ b/flutter/lib/desktop/pages/remote_page.dart
@@ -228,18 +228,12 @@ class _RemotePageState extends State
removeSharedStates(widget.id);
}
- Widget emptyOverlay() => GestureDetector(
- behavior: HitTestBehavior.translucent,
- onTap: () {
- bind.sessionInputOsPassword(sessionId: sessionId, value: '');
- },
- child: BlockableOverlay(
- /// the Overlay key will be set with _blockableOverlayState in BlockableOverlay
- /// see override build() in [BlockableOverlay]
- state: _blockableOverlayState,
- underlying: Container(
- color: Colors.transparent,
- ),
+ Widget emptyOverlay() => BlockableOverlay(
+ /// the Overlay key will be set with _blockableOverlayState in BlockableOverlay
+ /// see override build() in [BlockableOverlay]
+ state: _blockableOverlayState,
+ underlying: Container(
+ color: Colors.transparent,
),
);
@@ -273,7 +267,8 @@ class _RemotePageState extends State
inputModel: _ffi.inputModel,
child: getBodyForDesktop(context))),
Obx(
- () => _ffi.ffiModel.waitForFirstImage.isTrue
+ () => _ffi.ffiModel.pi.isSet.isTrue &&
+ _ffi.ffiModel.waitForFirstImage.isTrue
? emptyOverlay()
: Offstage(),
),
@@ -286,6 +281,9 @@ class _RemotePageState extends State
onEnterOrLeaveImageCleaner: () =>
_onEnterOrLeaveImage4Toolbar = null,
),
+ Obx(
+ () => _ffi.ffiModel.pi.isSet.isFalse ? emptyOverlay() : Offstage(),
+ ),
],
),
);
diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart
index 51bcec51d..1dd291e3b 100644
--- a/flutter/lib/desktop/pages/remote_tab_page.dart
+++ b/flutter/lib/desktop/pages/remote_tab_page.dart
@@ -20,6 +20,7 @@ import 'package:get/get.dart';
import 'package:bot_toast/bot_toast.dart';
import '../../common/widgets/dialog.dart';
+import '../../models/model.dart';
import '../../models/platform_model.dart';
class _MenuTheme {
@@ -266,7 +267,11 @@ class _ConnectionTabPageState extends State {
if (e.kind != ui.PointerDeviceKind.mouse) {
return;
}
- if (e.buttons == 2) {
+ final remotePage = tabController.state.value.tabs
+ .firstWhere((tab) => tab.key == key)
+ .page as RemotePage;
+ if (remotePage.ffi.ffiModel.pi.isSet.isTrue &&
+ e.buttons == 2) {
showRightMenu(
(CancelFunc cancelFunc) {
return _tabMenuBuilder(key, cancelFunc);
diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart
index 25ba22c70..00b344e13 100644
--- a/flutter/lib/models/model.dart
+++ b/flutter/lib/models/model.dart
@@ -99,6 +99,7 @@ class FfiModel with ChangeNotifier {
late final SessionID sessionId;
RxBool waitForImageDialogShow = true.obs;
+ Timer? waitForImageTimer;
RxBool waitForFirstImage = true.obs;
Map get permissions => _permissions;
@@ -159,6 +160,7 @@ class FfiModel with ChangeNotifier {
_timer?.cancel();
_timer = null;
clearPermissions();
+ waitForImageTimer?.cancel();
}
setConnectionType(String peerId, bool secure, bool direct) {
@@ -511,6 +513,11 @@ class FfiModel with ChangeNotifier {
tag: '$sessionId-waiting-for-image',
);
waitForImageDialogShow.value = true;
+ waitForImageTimer = Timer(Duration(milliseconds: 1500), () {
+ if (waitForFirstImage.isTrue) {
+ bind.sessionInputOsPassword(sessionId: sessionId, value: '');
+ }
+ });
bind.sessionOnWaitingForImageDialogShow(sessionId: sessionId);
}
@@ -603,6 +610,7 @@ class FfiModel with ChangeNotifier {
}
}
+ _pi.isSet.value = true;
stateGlobal.resetLastResolutionGroupValues(peerId);
notifyListeners();
@@ -1817,6 +1825,7 @@ class FFI {
void onEvent2UIRgba() async {
if (ffiModel.waitForImageDialogShow.isTrue) {
ffiModel.waitForImageDialogShow.value = false;
+ ffiModel.waitForImageTimer?.cancel();
clearWaitingForImage(dialogManager, sessionId);
}
if (ffiModel.waitForFirstImage.value == true) {
@@ -1935,7 +1944,7 @@ class Features {
bool privacyMode = false;
}
-class PeerInfo {
+class PeerInfo with ChangeNotifier {
String version = '';
String username = '';
String hostname = '';
@@ -1947,6 +1956,8 @@ class PeerInfo {
List resolutions = [];
Map platform_additions = {};
+ RxBool isSet = false.obs;
+
bool get is_wayland => platform_additions['is_wayland'] == true;
bool get is_headless => platform_additions['headless'] == true;
}
diff --git a/src/client.rs b/src/client.rs
index 17a62ed54..253c293ee 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -57,7 +57,10 @@ use scrap::{
ImageFormat, ImageRgb,
};
-use crate::is_keyboard_mode_supported;
+use crate::{
+ common::input::{MOUSE_BUTTON_LEFT, MOUSE_TYPE_DOWN, MOUSE_TYPE_UP},
+ is_keyboard_mode_supported,
+};
#[cfg(not(feature = "flutter"))]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
@@ -2057,13 +2060,20 @@ pub fn send_pointer_device_event(
/// # Arguments
///
/// * `interface` - The interface for sending data.
-fn activate_os(interface: &impl Interface) {
+/// * `send_click` - Whether to send a click event.
+fn activate_os(interface: &impl Interface, send_click: bool) {
+ let left_down = MOUSE_BUTTON_LEFT << 3 | MOUSE_TYPE_DOWN;
+ let left_up = MOUSE_BUTTON_LEFT << 3 | MOUSE_TYPE_UP;
+ send_mouse(left_up, 0, 0, false, false, false, false, interface);
+ std::thread::sleep(Duration::from_millis(50));
send_mouse(0, 0, 0, false, false, false, false, interface);
std::thread::sleep(Duration::from_millis(50));
send_mouse(0, 3, 3, false, false, false, false, interface);
- std::thread::sleep(Duration::from_millis(50));
- send_mouse(1 | 1 << 3, 0, 0, false, false, false, false, interface);
- send_mouse(2 | 1 << 3, 0, 0, false, false, false, false, interface);
+ if send_click {
+ std::thread::sleep(Duration::from_millis(50));
+ send_mouse(left_down, 0, 0, false, false, false, false, interface);
+ send_mouse(left_up, 0, 0, false, false, false, false, interface);
+ }
/*
let mut key_event = KeyEvent::new();
// do not use Esc, which has problem with Linux
@@ -2096,11 +2106,13 @@ pub fn input_os_password(p: String, activate: bool, interface: impl Interface) {
/// * `activate` - Whether to activate OS.
/// * `interface` - The interface for sending data.
fn _input_os_password(p: String, activate: bool, interface: impl Interface) {
+ let input_password = !p.is_empty();
if activate {
- activate_os(&interface);
+ // Click event is used to bring up the password input box.
+ activate_os(&interface, input_password);
std::thread::sleep(Duration::from_millis(1200));
}
- if p.is_empty() {
+ if !input_password {
return;
}
let mut key_event = KeyEvent::new();
From 23354d371f189b2a1b013875ab84a178e2f7295c Mon Sep 17 00:00:00 2001
From: Ibnul Mutaki
Date: Thu, 24 Aug 2023 11:07:47 +0700
Subject: [PATCH 56/75] change inconsitent word and add new translation
---
src/lang/id.rs | 44 ++++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/src/lang/id.rs b/src/lang/id.rs
index c8c343c5b..594d696a0 100644
--- a/src/lang/id.rs
+++ b/src/lang/id.rs
@@ -47,7 +47,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Slogan_tip", "Dibuat dengan penuh kasih sayang dalam dunia yang penuh kekacauan ini"),
("Privacy Statement", "Pernyataan Privasi"),
("Mute", "Bisukan"),
- ("Build Date", ""),
+ ("Build Date", "Tanggal Build"),
("Version", "Versi"),
("Home", ""),
("Audio Input", "Input Audio"),
@@ -172,7 +172,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Local Port", "Port Lokal"),
("Local Address", "Alamat lokal"),
("Change Local Port", "Ubah Port Lokal"),
- ("setup_server_tip", "Untuk koneksi yang lebih cepat, silakan atur server Anda sendiri"),
+ ("setup_server_tip", "Sudah siap, Untuk koneksi yang lebih stabil, anda bisa menjalankan di servermu sendiri"),
("Too short, at least 6 characters.", "Terlalu pendek, setidaknya 6 karekter."),
("The confirmation is not identical.", "Konfirmasi tidak identik."),
("Permissions", "Izin"),
@@ -186,13 +186,13 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Connected", "Terhubung"),
("Direct and encrypted connection", "Koneksi langsung dan terenkripsi"),
("Relayed and encrypted connection", "Koneksi relay dan terenkripsi"),
- ("Direct and unencrypted connection", "Koneksi langsung dan tidak terenkripsi"),
- ("Relayed and unencrypted connection", "Koneksi relay dan tidak terenkripsi"),
+ ("Direct and unencrypted connection", "Koneksi langsung dan tanpa enkripsi"),
+ ("Relayed and unencrypted connection", "Koneksi relay dan tanpa enkripsi"),
("Enter Remote ID", "Masukkan ID Remote"),
("Enter your password", "Masukkan kata sandi anda"),
("Logging in...", "Masuk..."),
("Enable RDP session sharing", "Aktifkan berbagi sesi RDP"),
- ("Auto Login", "Auto Login (Hanya berlaku jika Anda mengatur \"Kunci setelah sesi berakhir\")"),
+ ("Auto Login", "Login Otomatis (Hanya berlaku jika Anda mengatur \"Kunci setelah sesi berakhir\")"),
("Enable Direct IP Access", "Aktifkan Akses IP Langsung"),
("Rename", "Ubah nama"),
("Space", "Spasi"),
@@ -210,7 +210,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Settings", "Pengaturan"),
("Username", "Nama pengguna"),
("Invalid port", "Kesalahan port"),
- ("Closed manually by the peer", "Ditutup secara manual oleh peer"),
+ ("Closed manually by the peer", "Ditutup secara manual oleh rekan"),
("Enable remote configuration modification", "Aktifkan modifikasi konfigurasi remotE"),
("Run without install", "Jalankan tanpa menginstal"),
("Connect via relay", "Sambungkan via relay"),
@@ -301,7 +301,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Succeeded", "Berhasil"),
("Someone turns on privacy mode, exit", "Seseorang mengaktifkan mode privasi, keluar"),
("Unsupported", "Tidak didukung"),
- ("Peer denied", "Rekan ditolak"),
+ ("Peer denied", "Rekan menolak"),
("Please install plugins", "Silakan instal plugin"),
("Peer exit", "Rekan keluar"),
("Failed to turn off", "Gagal mematikan"),
@@ -311,7 +311,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Language", "Bahasa"),
("Keep RustDesk background service", "Pertahankan RustDesk berjalan pada service background"),
("Ignore Battery Optimizations", "Abaikan Pengoptimalan Baterai"),
- ("android_open_battery_optimizations_tip", "Jika kamu ingin menonaktifkan fitur ini, buka halam pengaturan, cari dan pilih [Baterai], Uncheck [Tidak dibatasi]"),
+ ("android_open_battery_optimizations_tip", "Jika anda ingin menonaktifkan fitur ini, buka halam pengaturan, cari dan pilih [Baterai], Uncheck [Tidak dibatasi]"),
("Start on Boot", "Mulai saat dihidupkan"),
("Start the screen sharing service on boot, requires special permissions", "Mulai layanan berbagi layar saat sistem dinyalakan, memerlukan izin khusus."),
("Connection not allowed", "Koneksi tidak dizinkan"),
@@ -321,9 +321,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Use permanent password", "Gunakan kata sandi permanaen"),
("Use both passwords", "Gunakan kedua kata sandi"),
("Set permanent password", "Setel kata sandi permanen"),
- ("Enable Remote Restart", "Aktifkan Restart Remote"),
- ("Allow remote restart", "Ijinkan Restart Remote"),
- ("Restart Remote Device", "Restart Perangkat Remote"),
+ ("Enable Remote Restart", "Aktifkan Restart Secara Remote"),
+ ("Allow remote restart", "Ijinkan Restart Secara Remote"),
+ ("Restart Remote Device", "Restart Perangkat Secara Remote"),
("Are you sure you want to restart", "Apakah Anda yakin ingin merestart"),
("Restarting Remote Device", "Merestart Perangkat Remote"),
("remote_restarting_tip", "Perangkat remote sedang merestart, harap tutup pesan ini dan sambungkan kembali dengan kata sandi permanen setelah beberapa saat."),
@@ -382,7 +382,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Write a message", "Menulis pesan"),
("Prompt", ""),
("Please wait for confirmation of UAC...", "Harap tunggu konfirmasi UAC"),
- ("elevated_foreground_window_tip", "Jendela remote desktop ini memerlukan hak akses khusus, jadi anda tidak bisa menggunakan mouse dan keyboard untuk sementara. Kamu bisa meminta pengguna remote untuk menyembunyikan jendela ini atau klik tombol elevasi di jendela pengaturan koneksi. Untuk menghindari masalah ini, direkomendasikan untuk menginstall aplikasi secara permanen"),
+ ("elevated_foreground_window_tip", "Jendela remote desktop ini memerlukan hak akses khusus, jadi anda tidak bisa menggunakan mouse dan keyboard untuk sementara. Anda bisa meminta pihak pengguna yang diremote untuk menyembunyikan jendela ini atau klik tombol elevasi di jendela pengaturan koneksi. Untuk menghindari masalah ini, direkomendasikan untuk menginstall aplikasi secara permanen"),
("Disconnected", "Terputus"),
("Other", "Lainnya"),
("Confirm before closing multiple tabs", "Konfirmasi sebelum menutup banyak tab"),
@@ -392,7 +392,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Wayland requires Ubuntu 21.04 or higher version.", "Wayland membutuhkan Ubuntu 21.04 atau versi yang lebih tinggi."),
("Wayland requires higher version of linux distro. Please try X11 desktop or change your OS.", "Wayland membutuhkan versi distro linux yang lebih tinggi. Silakan coba desktop X11 atau ubah OS Anda."),
("JumpLink", "Tautan Cepat"),
- ("Please Select the screen to be shared(Operate on the peer side).", "Silakan Pilih layar yang akan dibagikan kepada rekan."),
+ ("Please Select the screen to be shared(Operate on the peer side).", "Silakan Pilih layar yang akan dibagikan kepada rekan anda."),
("Show RustDesk", "Tampilkan RustDesk"),
("This PC", "PC ini"),
("or", "atau"),
@@ -418,7 +418,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Closed manually by web console", "Ditutup secara manual dari konsol web."),
("Local keyboard type", "Tipe papan ketik"),
("Select local keyboard type", "Pilih tipe papan ketik"),
- ("software_render_tip", "Jika kamu menggunakan kartu grafis Nvidia pada sistem linux dan jendela windows ditutup secara instan setelah terhung, silahkan ubah ke driver open-source Nouveau, dibutukan untuk merestart aplikasi"),
+ ("software_render_tip", "Jika anda menggunakan kartu grafis Nvidia pada sistem linux dan jendela windows ditutup secara instan setelah terhung, silahkan ubah ke driver open-source Nouveau, dibutukan untuk merestart aplikasi"),
("Always use software rendering", "Selalu gunakan software rendering"),
("config_input", "Untuk menggunakan input keyboard remote, anda perlu memberikan izin \"Pemantauan Input\" pada RustDesk"),
("config_microphone", "Untuk berbicara secara remote, anda perlu memberikan izin \"Rekam Audio\" pada RustDesk"),
@@ -440,7 +440,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Weak", "Lemah"),
("Medium", "Sedang"),
("Strong", "Kuat"),
- ("Switch Sides", "Tukar Posisi"),
+ ("Switch Sides", "Ganti Posisi"),
("Please confirm if you want to share your desktop?", "Harap konfirmasi apakah Anda ingin berbagi layar?"),
("Display", "Tampilan"),
("Default View Style", "Gaya Tampilan Default"),
@@ -470,14 +470,14 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Maximize", "Memaksimalkan"),
("Your Device", "Perangkat anda"),
("empty_recent_tip", "Tidak ada sesi terbaru!"),
- ("empty_favorite_tip", "Belum ada rekan (peer) favorit?\nTemukan seseorang untuk terhubung dan tambahkan ke favorit!"),
- ("empty_lan_tip", "Sepertinya kami belum menemukan rekan (peer)"),
+ ("empty_favorite_tip", "Belum ada rekan favorit?\nTemukan seseorang untuk terhubung dan tambahkan ke favorit!"),
+ ("empty_lan_tip", "Sepertinya kami belum menemukan rekan"),
("empty_address_book_tip", "Tampaknya saat ini tidak ada rekan yang terdaftar dalam buku alamat Anda"),
("eg: admin", ""),
("Empty Username", "Nama pengguna kosong"),
("Empty Password", "Kata sandi kosong"),
("Me", "Saya"),
- ("identical_file_tip", "Data ini identik dengan milik rekan (peer)"),
+ ("identical_file_tip", "Data ini identik dengan milik rekan"),
("show_monitors_tip", "Tampilkan monitor di toolbar"),
("View Mode", "Mode Tampilan"),
("login_linux_tip", "Anda harus masuk ke akun remote linux untuk mengaktifkan sesi X desktop"),
@@ -525,7 +525,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Sync with recent sessions", "Sinkronkan dengan sesi terbaru"),
("Sort tags", "Urutkan tag"),
("Open connection in new tab", "Buka koneksi di tab baru"),
- ("Move tab to new window", "Pindahkan tabn ke jendela baru"),
+ ("Move tab to new window", "Pindahkan tab ke jendela baru"),
("Can not be empty", "Tidak boleh kosong"),
("Already exists", "Sudah ada"),
("Change Password", "Ganti kata sandi"),
@@ -538,8 +538,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Gagal memuat ulang buku alamat"),
("push_ab_failed_tip", "Gagal menyinkronkan buku alamat ke server"),
("synced_peer_readded_tip", "Perangkat yang terdaftar dalam sesi-sesi terbaru akan di-sinkronkan kembali ke buku alamat."),
- ("Change Color", ""),
- ("Primary Color", ""),
- ("HSV Color", ""),
+ ("Change Color", "Ganti warna"),
+ ("Primary Color", "Warna utama"),
+ ("HSV Color", "Warna HSV"),
].iter().cloned().collect();
}
From a0887e9285c582bead6aed6d8210040ffdaa0ecc Mon Sep 17 00:00:00 2001
From: Ibnul Mutaki
Date: Thu, 24 Aug 2023 11:12:02 +0700
Subject: [PATCH 57/75] changed tips for better understanding
---
src/lang/id.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lang/id.rs b/src/lang/id.rs
index 594d696a0..7a1eaba20 100644
--- a/src/lang/id.rs
+++ b/src/lang/id.rs
@@ -172,7 +172,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Local Port", "Port Lokal"),
("Local Address", "Alamat lokal"),
("Change Local Port", "Ubah Port Lokal"),
- ("setup_server_tip", "Sudah siap, Untuk koneksi yang lebih stabil, anda bisa menjalankan di servermu sendiri"),
+ ("setup_server_tip", "Sudah siap, Untuk mendapatkan koneksi yang lebih baik, disarankan untuk menginstal di server anda sendiri"),
("Too short, at least 6 characters.", "Terlalu pendek, setidaknya 6 karekter."),
("The confirmation is not identical.", "Konfirmasi tidak identik."),
("Permissions", "Izin"),
From 257227920d7da51d0c4c5d38cfdd56051572bb56 Mon Sep 17 00:00:00 2001
From: fufesou
Date: Thu, 24 Aug 2023 12:24:08 +0800
Subject: [PATCH 58/75] Fix missing menu action
Signed-off-by: fufesou
---
flutter/lib/desktop/pages/remote_tab_page.dart | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart
index 1dd291e3b..4467adad4 100644
--- a/flutter/lib/desktop/pages/remote_tab_page.dart
+++ b/flutter/lib/desktop/pages/remote_tab_page.dart
@@ -20,7 +20,6 @@ import 'package:get/get.dart';
import 'package:bot_toast/bot_toast.dart';
import '../../common/widgets/dialog.dart';
-import '../../models/model.dart';
import '../../models/platform_model.dart';
class _MenuTheme {
@@ -359,7 +358,15 @@ class _ConnectionTabPageState extends State {
));
}
- if (perms['keyboard'] != false && !ffi.ffiModel.viewOnly) {}
+ if (perms['keyboard'] != false && !ffi.ffiModel.viewOnly) {
+ menu.add(RemoteMenuEntry.insertLock(sessionId, padding,
+ dismissFunc: cancelFunc));
+
+ if (pi.platform == kPeerPlatformLinux || pi.sasEnabled) {
+ menu.add(RemoteMenuEntry.insertCtrlAltDel(sessionId, padding,
+ dismissFunc: cancelFunc));
+ }
+ }
menu.addAll([
MenuEntryDivider(),
From c1a577797aef7b23fa4d80d34b6d7fca0dffc33d Mon Sep 17 00:00:00 2001
From: fufesou
Date: Thu, 24 Aug 2023 12:50:39 +0800
Subject: [PATCH 59/75] Revert Ctrl+Alt+Del in toolbar right menu
Signed-off-by: fufesou
---
flutter/lib/desktop/pages/remote_tab_page.dart | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart
index 4467adad4..bc4c6b243 100644
--- a/flutter/lib/desktop/pages/remote_tab_page.dart
+++ b/flutter/lib/desktop/pages/remote_tab_page.dart
@@ -358,15 +358,7 @@ class _ConnectionTabPageState extends State {
));
}
- if (perms['keyboard'] != false && !ffi.ffiModel.viewOnly) {
- menu.add(RemoteMenuEntry.insertLock(sessionId, padding,
- dismissFunc: cancelFunc));
-
- if (pi.platform == kPeerPlatformLinux || pi.sasEnabled) {
- menu.add(RemoteMenuEntry.insertCtrlAltDel(sessionId, padding,
- dismissFunc: cancelFunc));
- }
- }
+ if (perms['keyboard'] != false && !ffi.ffiModel.viewOnly) {}
menu.addAll([
MenuEntryDivider(),
From 56ff88934f238416d6c4ddd996191ddf55f30981 Mon Sep 17 00:00:00 2001
From: fufesou
Date: Thu, 24 Aug 2023 13:07:36 +0800
Subject: [PATCH 60/75] Add RemoteToolbar to Obx(()) to rebuild after pi is
recved
Signed-off-by: fufesou
---
flutter/lib/desktop/pages/remote_page.dart | 36 +++++++++++-----------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart
index f8151e059..091b0afaf 100644
--- a/flutter/lib/desktop/pages/remote_page.dart
+++ b/flutter/lib/desktop/pages/remote_page.dart
@@ -266,24 +266,24 @@ class _RemotePageState extends State
},
inputModel: _ffi.inputModel,
child: getBodyForDesktop(context))),
- Obx(
- () => _ffi.ffiModel.pi.isSet.isTrue &&
- _ffi.ffiModel.waitForFirstImage.isTrue
- ? emptyOverlay()
- : Offstage(),
- ),
- RemoteToolbar(
- id: widget.id,
- ffi: _ffi,
- state: widget.toolbarState,
- onEnterOrLeaveImageSetter: (func) =>
- _onEnterOrLeaveImage4Toolbar = func,
- onEnterOrLeaveImageCleaner: () =>
- _onEnterOrLeaveImage4Toolbar = null,
- ),
- Obx(
- () => _ffi.ffiModel.pi.isSet.isFalse ? emptyOverlay() : Offstage(),
- ),
+ Obx(() => Stack(
+ children: [
+ _ffi.ffiModel.pi.isSet.isTrue &&
+ _ffi.ffiModel.waitForFirstImage.isTrue
+ ? emptyOverlay()
+ : Offstage(),
+ RemoteToolbar(
+ id: widget.id,
+ ffi: _ffi,
+ state: widget.toolbarState,
+ onEnterOrLeaveImageSetter: (func) =>
+ _onEnterOrLeaveImage4Toolbar = func,
+ onEnterOrLeaveImageCleaner: () =>
+ _onEnterOrLeaveImage4Toolbar = null,
+ ),
+ _ffi.ffiModel.pi.isSet.isFalse ? emptyOverlay() : Offstage(),
+ ],
+ )),
],
),
);
From 9937650062e4185ba18b13625738b98550eb4e8d Mon Sep 17 00:00:00 2001
From: fufesou
Date: Thu, 24 Aug 2023 14:40:02 +0800
Subject: [PATCH 61/75] Use Overlay to wrap RemoteToolbar to enable rebuild
everytime on click
Signed-off-by: fufesou
---
flutter/lib/desktop/pages/remote_page.dart | 23 +++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart
index 091b0afaf..7e6e8ff86 100644
--- a/flutter/lib/desktop/pages/remote_page.dart
+++ b/flutter/lib/desktop/pages/remote_page.dart
@@ -238,6 +238,14 @@ class _RemotePageState extends State
);
Widget buildBody(BuildContext context) {
+ remoteToolbar(BuildContext context) => RemoteToolbar(
+ id: widget.id,
+ ffi: _ffi,
+ state: widget.toolbarState,
+ onEnterOrLeaveImageSetter: (func) =>
+ _onEnterOrLeaveImage4Toolbar = func,
+ onEnterOrLeaveImageCleaner: () => _onEnterOrLeaveImage4Toolbar = null,
+ );
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
body: Stack(
@@ -272,15 +280,12 @@ class _RemotePageState extends State
_ffi.ffiModel.waitForFirstImage.isTrue
? emptyOverlay()
: Offstage(),
- RemoteToolbar(
- id: widget.id,
- ffi: _ffi,
- state: widget.toolbarState,
- onEnterOrLeaveImageSetter: (func) =>
- _onEnterOrLeaveImage4Toolbar = func,
- onEnterOrLeaveImageCleaner: () =>
- _onEnterOrLeaveImage4Toolbar = null,
- ),
+ // Use Overlay to enable rebuild every time on menu button click.
+ _ffi.ffiModel.pi.isSet.isTrue
+ ? Overlay(initialEntries: [
+ OverlayEntry(builder: remoteToolbar)
+ ])
+ : remoteToolbar(context),
_ffi.ffiModel.pi.isSet.isFalse ? emptyOverlay() : Offstage(),
],
)),
From 63a19bc0a1df9c5f7da9557327fde73617b7b3d5 Mon Sep 17 00:00:00 2001
From: Jimmy GALLAND
Date: Thu, 24 Aug 2023 22:33:27 +0200
Subject: [PATCH 62/75] update fr.rs
---
src/lang/fr.rs | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/lang/fr.rs b/src/lang/fr.rs
index f9263d572..211927293 100644
--- a/src/lang/fr.rs
+++ b/src/lang/fr.rs
@@ -227,14 +227,14 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Search ID", "Rechercher un ID"),
("whitelist_sep", "Vous pouvez utiliser une virgule, un point-virgule, un espace ou une nouvelle ligne comme séparateur"),
("Add ID", "Ajouter un ID"),
- ("Add Tag", "Ajouter une balise"),
+ ("Add Tag", "Ajout étiquette(s)"),
("Unselect all tags", "Désélectionner toutes les étiquettes"),
("Network error", "Erreur réseau"),
("Username missed", "Nom d'utilisateur manquant"),
("Password missed", "Mot de passe manquant"),
("Wrong credentials", "Identifiant ou mot de passe erroné"),
("The verification code is incorrect or has expired", "Le code de vérification est incorrect ou a expiré"),
- ("Edit Tag", "Modifier la balise"),
+ ("Edit Tag", "Gestion étiquettes"),
("Unremember Password", "Oublier le Mot de passe"),
("Favorites", "Favoris"),
("Add to Favorites", "Ajouter aux Favoris"),
@@ -245,7 +245,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Hostname", "Nom d'hôte"),
("Discovered", "Découvert"),
("install_daemon_tip", "Pour une exécution au démarrage du système, vous devez installer le service système."),
- ("Remote ID", "ID de l'appareil à distance"),
+ ("Remote ID", "ID de l'appareil distant"),
("Paste", "Coller"),
("Paste here?", "Coller ici?"),
("Are you sure to close the connection?", "Êtes-vous sûr de fermer la connexion?"),
@@ -382,7 +382,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Write a message", "Ecrire un message"),
("Prompt", ""),
("Please wait for confirmation of UAC...", "Veuillez attendre la confirmation de l'UAC..."),
- ("elevated_foreground_window_tip", "La fenêtre actuelle que l'appareil distant nécessite des privilèges plus élevés pour fonctionner, elle ne peut donc pas être atteinte par la souris et le clavier. Vous pouvez demander à l'utilisateur distant de réduire la fenêtre actuelle ou de cliquer sur le bouton d'élévation dans la fenêtre de gestion des connexions. Pour éviter ce problème, il est recommandé d'installer le logiciel sur l'appareil distant."),
+ ("elevated_foreground_window_tip", "La fenêtre actuelle de l'appareil distant nécessite des privilèges plus élevés pour fonctionner, elle ne peut donc pas être atteinte par la souris et le clavier. Vous pouvez demander à l'utilisateur distant de réduire la fenêtre actuelle ou de cliquer sur le bouton d'élévation dans la fenêtre de gestion des connexions. Pour éviter ce problème, il est recommandé d'installer le logiciel sur l'appareil distant."),
("Disconnected", "Déconnecté"),
("Other", "Divers"),
("Confirm before closing multiple tabs", "Confirmer avant de fermer plusieurs onglets"),
@@ -452,7 +452,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Auto", "Auto"),
("Other Default Options", "Autres options par défaut"),
("Voice call", "Appel voix"),
- ("Text chat", "Conversation textuelfle"),
+ ("Text chat", "Conversation textuelle"),
("Stop voice call", "Stopper l'appel voix"),
("relay_hint_tip", "Il se peut qu'il ne doit pas possible de se connecter directement, vous pouvez essayer de vous connecter via un relais. \nEn outre, si vous souhaitez utiliser directement le relais, vous pouvez ajouter le suffixe \"/r\" à l'ID ou sélectionner l'option \"Toujours se connecter via le relais\" dans la fiche appareils distants."),
("Reconnect", "Se reconnecter"),
@@ -470,8 +470,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Maximize", "Maximiser"),
("Your Device", "Votre appareil"),
("empty_recent_tip", "Oups, pas de sessions récentes!\nIl est temps d'en prévoir une nouvelle."),
- ("empty_favorite_tip", "Vous n'avez pas encore d'appareils distants favorits?\nTrouvons quelqu'un avec qui vous connecter et ajoutez-la à vos favoris!"),
- ("empty_lan_tip", "Oh non, il semble que nous n'ayons pas encore d'appareil réseaux local découverts."),
+ ("empty_favorite_tip", "Vous n'avez pas encore d'appareils distants favorits?\nTrouvons quelqu'un avec qui vous connecter et ajoutez-les à vos favoris!"),
+ ("empty_lan_tip", "Oh non, il semble que nous n'ayons pas encore d'appareils réseau local découverts."),
("empty_address_book_tip", "Ouh là là! il semble qu'il n'y ait actuellement aucun appareil distant répertorié dans votre carnet d'adresses."),
("eg: admin", "ex: admin"),
("Empty Username", "Nom d'utilisation non spécifié"),
@@ -538,8 +538,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("pull_ab_failed_tip", "Impossible d'actualiser le carnet d'adresses"),
("push_ab_failed_tip", "Échec de la synchronisation du carnet d'adresses"),
("synced_peer_readded_tip", "Les appareils qui étaient présents dans les sessions récentes seront synchronisés avec le carnet d'adresses."),
- ("Change Color", ""),
- ("Primary Color", ""),
- ("HSV Color", ""),
+ ("Change Color", "Modifier la couleur"),
+ ("Primary Color", "Couleur primaire"),
+ ("HSV Color", "Couleur TSL"),
].iter().cloned().collect();
-}
+}
\ No newline at end of file
From a957acd893e83417ce8adb99134250083c1ef97a Mon Sep 17 00:00:00 2001
From: rustdesk
Date: Fri, 25 Aug 2023 15:19:00 +0800
Subject: [PATCH 63/75] remove LSUIElement=1 in info.plist so that system menu
can be shown
---
build.py | 7 -------
flutter/macos/Runner/Info.plist | 2 --
2 files changed, 9 deletions(-)
diff --git a/build.py b/build.py
index 73ea8186d..42dc8d6de 100755
--- a/build.py
+++ b/build.py
@@ -545,13 +545,6 @@ def main():
'cp libsciter.dylib target/release/bundle/osx/RustDesk.app/Contents/MacOS/')
# https://github.com/sindresorhus/create-dmg
system2('/bin/rm -rf *.dmg')
- plist = "target/release/bundle/osx/RustDesk.app/Contents/Info.plist"
- txt = open(plist).read()
- with open(plist, "wt") as fh:
- fh.write(txt.replace("", """
- LSUIElement
- 1
- """))
pa = os.environ.get('P')
if pa:
system2('''
diff --git a/flutter/macos/Runner/Info.plist b/flutter/macos/Runner/Info.plist
index 96616e8c4..ff9322417 100644
--- a/flutter/macos/Runner/Info.plist
+++ b/flutter/macos/Runner/Info.plist
@@ -37,8 +37,6 @@
$(FLUTTER_BUILD_NUMBER)
LSMinimumSystemVersion
$(MACOSX_DEPLOYMENT_TARGET)
- LSUIElement
- 1
NSHumanReadableCopyright
$(PRODUCT_COPYRIGHT)
NSMainNibFile
From 0e9950638c9e66f7cb64d1250a5ad8a6aec2426b Mon Sep 17 00:00:00 2001
From: Mert Sonmez <109958428+SnmzTony@users.noreply.github.com>
Date: Fri, 25 Aug 2023 12:21:33 +0300
Subject: [PATCH 64/75] Create README-TR.md
---
docs/README-TR.md | 223 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 223 insertions(+)
create mode 100644 docs/README-TR.md
diff --git a/docs/README-TR.md b/docs/README-TR.md
new file mode 100644
index 000000000..efc8aa1d8
--- /dev/null
+++ b/docs/README-TR.md
@@ -0,0 +1,223 @@
+
+
+
+ Sunucular •
+ Derleme •
+ Docker ile Derleme •
+ Dosya Yapısı •
+ Ekran Görüntüleri
+ [Українська ] | [česky ] | [中文 ] | [Magyar ] | [Español ] | [فارسی ] | [Français ] | [Deutsch ] | [Polski ] | [Indonesian ] | [Suomi ] | [മലയാളം ] | [日本語 ] | [Nederlands ] | [Italiano ] | [Русский ] | [Português (Brasil) ] | [Esperanto ] | [한국어 ] | [العربي ] | [Tiếng Việt ] | [Dansk ] | [Ελληνικά ]
+ README, RustDesk UI ve RustDesk Belge 'sini ana dilinize çevirmemiz için yardımınıza ihtiyacımız var
+
+
+Bizimle sohbet edin: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
+
+[](https://ko-fi.com/I2I04VU09)
+
+Başka bir uzak masaüstü yazılımı daha, Rust dilinde yazılmış. Hemen kullanıma hazır, hiçbir yapılandırma gerektirmez. Verilerinizin tam kontrolünü elinizde tutarsınız ve güvenlikle ilgili endişeleriniz olmaz. Kendi buluş/iletme sunucumuzu kullanabilirsiniz, [kendi sunucunuzu kurabilirsiniz](https://rustdesk.com/server) veya [kendi buluş/iletme sunucunuzu yazabilirsiniz](https://github.com/rustdesk/rustdesk-server-demo).
+
+
+
+RustDesk, herkesten katkıyı kabul eder. Başlamak için [CONTRIBUTING.md](docs/CONTRIBUTING.md) belgesine göz atın.
+
+[**SSS**](https://github.com/rustdesk/rustdesk/wiki/FAQ)
+
+[**BİNARİ İNDİR**](https://github.com/rustdesk/rustdesk/releases)
+
+[**NİGHTLY DERLEME**](https://github.com/rustdesk/rustdesk/releases/tag/nightly)
+
+[ ](https://f-droid.org/en/packages/com.carriez.flutter_hbb)
+
+## Ücretsiz Genel Sunucular
+
+Aşağıda ücretsiz olarak kullandığınız sunucular listelenmiştir, zaman içinde değişebilirler. Eğer bunlardan birine yakın değilseniz, ağınız yavaş olabilir.
+| Konum | Sağlayıcı | Özellikler |
+| --------- | ------------- | ------------------ |
+| Almanya | [Hetzner](https://www.hetzner.com) | 2 vCPU / 4 GB RAM |
+| Almanya | [Codext](https://codext.de) | 4 vCPU / 8 GB RAM |
+| Ukrayna (Kiev) | [dc.volia](https://dc.volia.com) | 2 vCPU / 4 GB RAM |
+
+## Geliştirici Konteyneri
+
+[](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/rustdesk/rustdesk)
+
+Eğer zaten VS Code ve Docker kurulu ise yukarıdaki rozete tıklayarak başlayabilirsiniz. Tıklamak, VS Code'un gerektiğinde Dev Konteyner eklentisini otomatik olarak yüklemesine, kaynak kodunu bir konteyner hacmine klonlamasına ve kullanım için bir geliştirici konteyneri başlatmasına neden olur.
+
+Daha fazla bilgi için [DEVCONTAINER.md](docs/DEVCONTAINER.md) belgesine bakabilirsiniz.
+
+## Bağımlılıklar
+
+Masaüstü sürümleri GUI için
+
+ [Sciter](https://sciter.com/) veya Flutter kullanır, bu kılavuz sadece Sciter içindir.
+
+Lütfen Sciter dinamik kütüphanesini kendiniz indirin.
+
+[Windows](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.win/x64/sciter.dll) |
+[Linux](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so) |
+[macOS](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.osx/libsciter.dylib)
+
+## Temel Derleme Adımları
+
+- Rust geliştirme ortamınızı ve C++ derleme ortamınızı hazırlayın.
+
+- [vcpkg](https://github.com/microsoft/vcpkg) yükleyin ve `VCPKG_ROOT` çevresel değişkenini doğru bir şekilde ayarlayın.
+
+ - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static aom:x64-windows-static
+ - Linux/macOS: vcpkg install libvpx libyuv opus aom
+
+- `cargo run` komutunu çalıştırın.
+
+## [Derleme](https://rustdesk.com/docs/en/dev/build/)
+
+## Linux Üzerinde Derleme Nasıl Yapılır
+
+### Ubuntu 18 (Debian 10)
+
+```sh
+sudo apt install -y zip g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev \
+ libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake make \
+ libclang-dev ninja-build libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
+```
+
+### openSUSE Tumbleweed
+
+```sh
+sudo zypper install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libXfixes-devel cmake alsa-lib-devel gstreamer-devel gstreamer-plugins-base-devel xdotool-devel
+```
+
+### Fedora 28 (CentOS 8)
+
+```sh
+sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libxdo-devel libXfixes-devel pulseaudio-libs-devel cmake alsa-lib-devel
+```
+
+### Arch (Manjaro)
+
+```sh
+sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pipewire
+```
+
+### vcpkg'yi Yükleyin
+
+```sh
+git clone https://github.com/microsoft/vcpkg
+cd vcpkg
+git checkout 2023.04.15
+cd ..
+vcpkg/bootstrap-vcpkg.sh
+export VCPKG_ROOT=$HOME/vcpkg
+vcpkg/vcpkg install libvpx libyuv opus aom
+```
+
+### libvpx'i Düzeltin (Fedora için)
+
+```sh
+cd vcpkg/buildtrees/libvpx/src
+cd *
+./configure
+sed -i 's/CFLAGS+=-I/CFLAGS+=-fPIC -I/g' Makefile
+sed -i 's/CXXFLAGS+=-I/CXXFLAGS+=-fPIC -I/g' Makefile
+make
+cp libvpx.a $HOME/vcpkg/installed/x64-linux/lib/
+cd
+```
+
+### Derleme
+
+```sh
+curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+source $HOME/.cargo/env
+git clone https://github.com/rustdesk/rustdesk
+cd rustdesk
+mkdir -p target/debug
+wget https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so
+mv libsciter-gtk.so target/debug
+VCPKG_ROOT=$HOME/vcpkg cargo run
+```
+
+### Wayland'ı X11 (Xorg) Olarak Değiştirme
+
+RustDesk, Wayland'ı desteklemez. Xorg'u GNOME oturumu olarak varsayılan olarak ayarlamak için [burayı](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) kontrol edin.
+
+## Wayland Desteği
+
+Wayland'ın diğer pencerelere tuş vuruşu göndermek için herhangi bir API sağlamadığı görünmektedir. Bu nedenle, RustDesk daha düşük bir seviyeden, yani Linux çekirdek seviyesindeki `/dev/uinput` cihazının API'sini kullanır.
+
+Wayland tarafı kontrol edildiğinde, aşağıdaki şekilde başlatmanız gerekir:
+```bash
+# uinput servisini başlatın
+$ sudo rustdesk --service
+$ rustdesk
+```
+**Uyarı**: Wayland ekran kaydı farklı arayüzler kullanır. RustDesk şu anda yalnızca org.freedesktop.portal.ScreenCast'ı destekler.
+```bash
+$ dbus-send --session --print-reply \
+ --dest=org.freedesktop.portal.Desktop \
+ /org/freedesktop/portal/desktop \
+ org.freedesktop.DBus.Properties.Get \
+ string:org.freedesktop.portal.ScreenCast string:version
+# Desteklenmez
+Error org.freedesktop.DBus.Error.InvalidArgs: No such interface “org.freedesktop.portal.ScreenCast”
+# Desteklenir
+method return time=1662544486.931020 sender=:1.54 -> destination=:1.139 serial=257 reply_serial=2
+ variant uint32 4
+```
+
+## Docker ile Derleme Nasıl Yapılır
+
+Öncelikle deposunu klonlayın ve Docker konteynerini oluşturun:
+
+```sh
+git clone https://github.com/rustdesk/rustdesk
+cd rustdesk
+docker build -t "rustdesk-builder" .
+```
+
+Ardından, uygulamayı derlemek için her seferinde aşağıdaki komutu çalıştırın:
+
+```sh
+docker run --rm -it -v $PWD:/home/user/rustdesk -v rustdesk-git-cache:/home/user/.cargo/git -v rustdesk-registry-cache:/home/user/.cargo/registry -e PUID="$(id -u)" -e PGID="$(id -g)" rustdesk-builder
+```
+
+İlk derleme, bağımlılıklar önbelleğe alınmadan önce daha uzun sürebilir, sonraki derlemeler daha hızlı olacaktır. Ayrıca, derleme komutuna isteğe bağlı argümanlar belirtmeniz gerekiyorsa, bunu
+
+ komutun sonunda `<İSTEĞE BAĞLI-ARGÜMANLAR>` pozisyonunda yapabilirsiniz. Örneğin, optimize edilmiş bir sürümü derlemek isterseniz, yukarıdaki komutu çalıştırdıktan sonra `--release` ekleyebilirsiniz. Oluşan yürütülebilir dosya sisteminizdeki hedef klasöründe bulunacak ve şu komutla çalıştırılabilir:
+
+```sh
+target/debug/rustdesk
+```
+
+Veya, yayın yürütülebilir dosyası çalıştırılıyorsa:
+
+```sh
+target/release/rustdesk
+```
+
+Lütfen bu komutları RustDesk deposunun kökünden çalıştırdığınızdan emin olun, aksi takdirde uygulama gereken kaynakları bulamayabilir. Ayrıca, `install` veya `run` gibi diğer cargo altkomutları şu anda bu yöntem aracılığıyla desteklenmemektedir, çünkü bunlar programı konteyner içinde kurar veya çalıştırır ve ana makinede değil.
+
+## Dosya Yapısı
+
+- **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)**: video kodlayıcı, yapılandırma, tcp/udp sarmalayıcı, protobuf, dosya transferi için fs işlevleri ve diğer bazı yardımcı işlevler
+- **[libs/scrap](https://github.com/rustdesk/rustdesk/tree/master/libs/scrap)**: ekran yakalama
+- **[libs/enigo](https://github.com/rustdesk/rustdesk/tree/master/libs/enigo)**: platforma özgü klavye/fare kontrolü
+- **[src/ui](https://github.com/rustdesk/rustdesk/tree/master/src/ui)**: GUI
+- **[src/server](https://github.com/rustdesk/rustdesk/tree/master/src/server)**: ses/pasta/klavye/video hizmetleri ve ağ bağlantıları
+- **[src/client.rs](https://github.com/rustdesk/rustdesk/tree/master/src/client.rs)**: bir eş bağlantısı başlatır
+- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: [rustdesk-server](https://github.com/rustdesk/rustdesk-server) ile iletişim kurar, uzak doğrudan (TCP delik vurma) veya iletme bağlantısını bekler
+- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: platforma özgü kod
+- **[flutter](https://github.com/rustdesk/rustdesk/tree/master/flutter)**: mobil için Flutter kodu
+- **[flutter/web/js](https://github.com/rustdesk/rustdesk/tree/master/flutter/web/js)**: Flutter web istemcisi için JavaScript
+
+## Ekran Görüntüleri
+
+
+
+
+
+
+
+
+```
From 80082b0880c09bf6c1e77957db6d01584062ece7 Mon Sep 17 00:00:00 2001
From: Mert Sonmez <109958428+SnmzTony@users.noreply.github.com>
Date: Fri, 25 Aug 2023 14:32:27 +0300
Subject: [PATCH 65/75] Create CODE_OF_CONDUCT-TR.md
---
docs/CODE_OF_CONDUCT-TR.md | 89 ++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
create mode 100644 docs/CODE_OF_CONDUCT-TR.md
diff --git a/docs/CODE_OF_CONDUCT-TR.md b/docs/CODE_OF_CONDUCT-TR.md
new file mode 100644
index 000000000..76088bd95
--- /dev/null
+++ b/docs/CODE_OF_CONDUCT-TR.md
@@ -0,0 +1,89 @@
+# Katkıda Bulunanların Davranış Kuralları
+
+## Taahhüdümüz
+
+Biz üyeler, katkıda bulunanlar ve liderler olarak, yaş, beden büyüklüğü, görünür veya görünmez engellilik, etnik köken, cinsiyet özellikleri, cinsiyet kimliği ve ifadesi, deneyim seviyesi, eğitim, sosyo-ekonomik durum, milliyet, kişisel görünüm, ırk, din veya cinsel kimlik ve yönelim ayrımı gözetmeksizin herkes için topluluğumuzdaki katılımı taciz içermeyen bir deneyim haline getirmeyi taahhüt ederiz.
+
+Açık, hoşgörülü, çeşitli, kapsayıcı ve sağlıklı bir topluluğa katkıda bulunacak şekillerde hareket etmeyi ve etkileşimde bulunmayı taahhüt ederiz.
+
+## Standartlarımız
+
+Topluluğumuz için olumlu bir ortam yaratmaya katkıda bulunan davranış örnekleri şunlardır:
+
+* Diğer insanlara empati ve nezaket göstermek
+* Farklı görüşlere, bakış açılarına ve deneyimlere saygılı olmak
+* Yapıcı eleştiriyi vermek ve zarifçe kabul etmek
+* Hatalarımızdan etkilenenlere sorumluluk kabul etmek, özür dilemek ve deneyimden öğrenmek
+* Sadece bireyler olarak değil, aynı zamanda genel topluluk için en iyisi üzerine odaklanmak
+
+Kabul edilemez davranış örnekleri şunları içerir:
+
+* Cinselleştirilmiş dil veya imgelerin kullanımı ve cinsel ilgi veya herhangi bir türdeki yaklaşımlar
+* Trollük, aşağılayıcı veya hakaret içeren yorumlar ve kişisel veya siyasi saldırılar
+* Kamuoyu veya özel taciz
+* Başkalarının fiziksel veya e-posta adresi gibi özel bilgilerini, açık izinleri olmadan yayınlamak
+* Profesyonel bir ortamda makul bir şekilde uygunsuz kabul edilebilecek diğer davranışlar
+
+## Uygulama Sorumlulukları
+
+Topluluk liderleri, kabul edilebilir davranış standartlarımızı açıklığa kavuşturmak ve uygulamakla sorumludur ve uygunsuz, tehditkar, saldırgan veya zarar verici herhangi bir davranışa yanıt olarak uygun ve adil düzeltici önlemler alacaklardır.
+
+Topluluk liderleri, bu Davranış Kurallarına uyumlu olmayan yorumları, taahhütlerini veya kodu, wiki düzenlemelerini, sorunları ve diğer katkıları kaldırma, düzenleme veya reddetme hakkına sahiptir. Denetim kararlarının nedenlerini uygun olduğunda ileteceklerdir.
+
+## Kapsam
+
+Bu Davranış Kuralları, tüm topluluk alanlarında geçerlidir ve aynı zamanda birey resmi olarak topluluğu halka açık alanlarda temsil ettiğinde de geçerlidir. Topluluğumuzu temsil etme örnekleri, resmi bir e-posta adresi kullanmak, resmi bir sosyal medya hesabı üzerinden gönderi yapmak veya çevrimiçi veya çevrimdışı bir etkinlikte atanmış bir temsilci olarak hareket etmeyi içerir.
+
+## Uygulama
+
+Taciz edici, rahatsız edici veya başka türlü kabul edilemez davranış örnekleri, [info@rustdesk.com](mailto:info@rustdesk.com) adresindeki uygulama sorumlularına bildirilebilir. Tüm şikayetler hızlı ve adil bir şekilde incelenecek ve araştırılacaktır.
+
+Tüm topluluk liderleri, olayın raporlayıcısının gizliliğine ve güvenliğine saygı gösterme yükümlülüğündedir.
+
+## Uygulama Kılavuzları
+
+Topluluk liderleri, bu Davranış Kurallarını ihlal olarak değerlendirdikleri herhangi bir eylem için bu Topluluk Etkisi Kılavuzlarını izleyeceklerdir:
+
+### 1. Düzeltme
+
+**Topluluk Etkisi**: Topluluk içinde profesyonel veya hoşgörülü olmayan uygun olmayan dil veya diğer davranışların kullanımı.
+
+**Sonuç**: Topluluk liderlerinden özel ve yazılı bir uyarı almak, ihlalin niteliği ve davranışın nedeninin açıklığa kavuşturulması. Bir kamu özrü istenebilir.
+
+### 2. Uyarı
+
+**Topluluk Etkisi**: Tek bir olay veya dizi aracılığıyla bir ihlal.
+
+**Sonuç**: Devam eden davranış için sonuçları olan bir uyarı. Topluluk liderleri de dahil olmak üzere ihlalle ilgili kişilerle etkileşim, belirli bir süre boyunca önerilmez. Bu, topluluk alanlarında ve sosyal medya gibi harici kanallarda etkileşimleri içerir. Bu koşulları ihlal etmek geçici veya kalıcı bir yasağa yol açabilir.
+
+### 3. Geçici Yasak
+
+**Topluluk Etkisi**: Sürekli uygunsuz davranış da dahil olmak üzere topluluk standartlarının ciddi bir ihlali.
+
+**Sonuç**: Belirli bir süre için toplulukla herhangi bir türdeki etkileşim veya halka açık iletişimden geçici bir yasak. Bu dönem boyunca, toplul
+
+ukla veya uygulama kurallarını uygulayanlarla her türlü kamuoyu veya özel etkileşim izin verilmez. Bu koşulları ihlal etmek geçici veya kalıcı bir yasağa yol açabilir.
+
+### 4. Kalıcı Yasak
+
+**Topluluk Etkisi**: Topluluk standartlarının ihlalinde sürekli bir desen sergilemek, bireye sürekli olarak uygun olmayan davranışlarda bulunmak, bir bireye tacizde bulunmak veya birey sınıflarına karşı saldırganlık veya aşağılama yapmak.
+
+**Sonuç**: Topluluk içinde her türlü halka açık etkileşimden kalıcı bir yasak.
+
+## Atıf
+
+Bu Davranış Kuralları, [Contributor Covenant][anasayfa], 2.0 sürümünden uyarlanmıştır ve
+[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0] adresinde bulunmaktadır.
+
+Topluluk Etkisi Kılavuzları,
+[Mozilla'nın davranış kuralları uygulama merdiveni][Mozilla DK] tarafından ilham alınarak oluşturulmuştur.
+
+Bu davranış kuralları hakkında yaygın soruların cevapları için, SSS'ye göz atın:
+[https://www.contributor-covenant.org/faq][SSS]. Çeviriler,
+[https://www.contributor-covenant.org/translations][çeviriler] adresinde bulunabilir.
+
+[anasayfa]: https://www.contributor-covenant.org
+[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
+[Mozilla DK]: https://github.com/mozilla/diversity
+[SSS]: https://www.contributor-covenant.org/faq
+[çeviriler]: https://www.contributor-covenant.org/translations
From dd5c9939a04263b204555aea2235b3a61e76546a Mon Sep 17 00:00:00 2001
From: Mert Sonmez <109958428+SnmzTony@users.noreply.github.com>
Date: Fri, 25 Aug 2023 14:35:45 +0300
Subject: [PATCH 66/75] Create CONTRIBUTING-TR.md
---
docs/CONTRIBUTING-TR.md | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 docs/CONTRIBUTING-TR.md
diff --git a/docs/CONTRIBUTING-TR.md b/docs/CONTRIBUTING-TR.md
new file mode 100644
index 000000000..6e9e3f3ed
--- /dev/null
+++ b/docs/CONTRIBUTING-TR.md
@@ -0,0 +1,31 @@
+# RustDesk'a Katkı Sağlamak
+
+RustDesk, herkesten katkıyı memnuniyetle karşılar. Eğer bize yardımcı olmayı düşünüyorsanız, işte rehberlik eden kurallar:
+
+## Katkılar
+
+RustDesk veya bağımlılıklarına yapılan katkılar, GitHub pull istekleri şeklinde yapılmalıdır. Her bir pull isteği, çekirdek katkıcı tarafından gözden geçirilecek (yamaları kabul etme izni olan biri) ve ana ağaca kabul edilecek veya gerekli değişiklikler için geri bildirim verilecektir. Tüm katkılar bu formata uymalıdır, çekirdek katkıcılardan gelenler bile.
+
+Eğer bir konu üzerinde çalışmak isterseniz, önce üzerinde çalışmak istediğinizi belirten bir yorum yaparak konuyu talep ediniz. Bu, katkı sağlayanların aynı konuda çift çalışmasını engellemek içindir.
+
+## Pull İstek Kontrol Listesi
+
+- Master dalından dallandırın ve gerekiyorsa pull isteğinizi göndermeden önce mevcut master dalına rebase yapın. Eğer master ile temiz bir şekilde birleşmezse, değişikliklerinizi rebase yapmanız istenebilir.
+
+- Her bir commit mümkün olduğunca küçük olmalıdır, ancak her commit'in bağımsız olarak doğru olduğundan emin olun (örneğin, her commit derlenebilir ve testleri geçmelidir).
+
+- Commit'ler, bir Geliştirici Sertifikası ile desteklenmelidir (http://developercertificate.org). Bu, [proje lisansının](../LICENCE) koşullarına uymayı kabul ettiğinizi gösteren bir onaydır. Git'te bunu `git commit` seçeneği olarak `-s` seçeneği ile yapabilirsiniz.
+
+- Yamalarınız gözden geçirilmiyorsa veya belirli bir kişinin gözden geçirmesine ihtiyacınız varsa, çekme isteği veya yorum içinde bir gözden geçirmeyi istemek için bir inceleyiciyi @etiketleyebilir veya inceleme için [e-posta](mailto:info@rustdesk.com) ile talep edebilirsiniz.
+
+- Düzelttiğiniz hatanın veya eklediğiniz yeni özelliğin ilgili testlerini ekleyin.
+
+Daha spesifik git talimatları için, [GitHub iş akışı 101](https://github.com/servo/servo/wiki/GitHub-workflow)'e bakınız.
+
+## Davranış
+
+https://github.com/rustdesk/rustdesk/blob/master/docs/CODE_OF_CONDUCT-TR.md
+
+## İletişim
+
+RustDesk katkı sağlayıcıları, [Discord](https://discord.gg/nDceKgxnkV) kanalını sık sık ziyaret ederler.
From c618bdfe910c48bafe7bd3ca838b16d9ac46c41d Mon Sep 17 00:00:00 2001
From: Mert Sonmez <109958428+SnmzTony@users.noreply.github.com>
Date: Fri, 25 Aug 2023 14:36:28 +0300
Subject: [PATCH 67/75] Update README-TR.md
---
docs/README-TR.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/README-TR.md b/docs/README-TR.md
index efc8aa1d8..18f2ed2c5 100644
--- a/docs/README-TR.md
+++ b/docs/README-TR.md
@@ -18,7 +18,7 @@ Başka bir uzak masaüstü yazılımı daha, Rust dilinde yazılmış. Hemen kul

-RustDesk, herkesten katkıyı kabul eder. Başlamak için [CONTRIBUTING.md](docs/CONTRIBUTING.md) belgesine göz atın.
+RustDesk, herkesten katkıyı kabul eder. Başlamak için [CONTRIBUTING.md](docs/CONTRIBUTING-TR.md) belgesine göz atın.
[**SSS**](https://github.com/rustdesk/rustdesk/wiki/FAQ)
From 3162fcf154727f354a3c75eb9bd6304374674e3e Mon Sep 17 00:00:00 2001
From: Mert Sonmez <109958428+SnmzTony@users.noreply.github.com>
Date: Fri, 25 Aug 2023 14:38:38 +0300
Subject: [PATCH 68/75] Create SECURITY-TR.md
---
docs/SECURITY-TR.md | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 docs/SECURITY-TR.md
diff --git a/docs/SECURITY-TR.md b/docs/SECURITY-TR.md
new file mode 100644
index 000000000..88037acb2
--- /dev/null
+++ b/docs/SECURITY-TR.md
@@ -0,0 +1,9 @@
+# Güvenlik Politikası
+
+## Bir Güvenlik Açığı Bildirme
+
+Projemiz için güvenliği çok önemsiyoruz. Kullanıcıların keşfettikleri herhangi bir güvenlik açığını bize bildirmelerini teşvik ediyoruz.
+Eğer RustDesk projesinde bir güvenlik açığı bulursanız, lütfen info@rustdesk.com adresine sorumlu bir şekilde bildirin.
+
+Şu an için bir hata ödül programımız bulunmamaktadır. Büyük bir sorunu çözmeye çalışan küçük bir ekibiz. Herhangi bir güvenlik açığını sorumlu bir şekilde bildirmenizi rica ederiz,
+böylece tüm topluluk için güvenli bir uygulama oluşturmaya devam edebiliriz.
From 77fa3bd7fc6583162e8cc405fa7ba0e7064bd5f8 Mon Sep 17 00:00:00 2001
From: Mert Sonmez <109958428+SnmzTony@users.noreply.github.com>
Date: Fri, 25 Aug 2023 14:40:02 +0300
Subject: [PATCH 69/75] Create DEVCONTAINER-TR.md
---
docs/DEVCONTAINER-TR.md | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 docs/DEVCONTAINER-TR.md
diff --git a/docs/DEVCONTAINER-TR.md b/docs/DEVCONTAINER-TR.md
new file mode 100644
index 000000000..7fc14ce5e
--- /dev/null
+++ b/docs/DEVCONTAINER-TR.md
@@ -0,0 +1,12 @@
+Docker konteynerinde devcontainer'ın başlatılmasından sonra, hata ayıklama modunda bir Linux ikili dosyası oluşturulur.
+
+Şu anda devcontainer, hata ayıklama ve sürüm modunda hem Linux hem de Android derlemeleri sunmaktadır.
+
+Aşağıda, belirli derlemeler oluşturmak için projenin kökünden çalıştırılması gereken komutlar yer almaktadır.
+
+Komut | Derleme Türü | Mod
+-|-|-
+`.devcontainer/build.sh --debug linux` | Linux | hata ayıklama
+`.devcontainer/build.sh --release linux` | Linux | sürüm
+`.devcontainer/build.sh --debug android` | Android-arm64 | hata ayıklama
+`.devcontainer/build.sh --release android` | Android-arm64 | sürüm
From d1bc8a72028e6a4dd5d7d9823db23abd7b369fbf Mon Sep 17 00:00:00 2001
From: Mert Sonmez <109958428+SnmzTony@users.noreply.github.com>
Date: Fri, 25 Aug 2023 14:41:37 +0300
Subject: [PATCH 70/75] Update README-TR.md
---
docs/README-TR.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/README-TR.md b/docs/README-TR.md
index 18f2ed2c5..fa1f79c37 100644
--- a/docs/README-TR.md
+++ b/docs/README-TR.md
@@ -45,7 +45,7 @@ Aşağıda ücretsiz olarak kullandığınız sunucular listelenmiştir, zaman i
Eğer zaten VS Code ve Docker kurulu ise yukarıdaki rozete tıklayarak başlayabilirsiniz. Tıklamak, VS Code'un gerektiğinde Dev Konteyner eklentisini otomatik olarak yüklemesine, kaynak kodunu bir konteyner hacmine klonlamasına ve kullanım için bir geliştirici konteyneri başlatmasına neden olur.
-Daha fazla bilgi için [DEVCONTAINER.md](docs/DEVCONTAINER.md) belgesine bakabilirsiniz.
+Daha fazla bilgi için [DEVCONTAINER.md](docs/DEVCONTAINER-TR.md) belgesine bakabilirsiniz.
## Bağımlılıklar
From 301abcaa493d76cf8ad705e19159fa4b004b9d23 Mon Sep 17 00:00:00 2001
From: Mert Sonmez <109958428+SnmzTony@users.noreply.github.com>
Date: Fri, 25 Aug 2023 16:10:09 +0300
Subject: [PATCH 71/75] Update tr.rs
---
src/lang/tr.rs | 266 ++++++++++++++++++++++++-------------------------
1 file changed, 133 insertions(+), 133 deletions(-)
diff --git a/src/lang/tr.rs b/src/lang/tr.rs
index 3c3a10da2..f8295e2c4 100644
--- a/src/lang/tr.rs
+++ b/src/lang/tr.rs
@@ -408,138 +408,138 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("One-time password length", "Tek seferlik şifre uzunluğu"),
("Request access to your device", "Cihazınıza erişim talep edin"),
("Hide connection management window", "Bağlantı yönetimi penceresini gizle"),
- ("hide_cm_tip", ""),
- ("wayland_experiment_tip", ""),
- ("Right click to select tabs", ""),
- ("Skipped", ""),
- ("Add to Address Book", ""),
- ("Group", ""),
- ("Search", ""),
- ("Closed manually by web console", ""),
- ("Local keyboard type", ""),
- ("Select local keyboard type", ""),
- ("software_render_tip", ""),
- ("Always use software rendering", ""),
- ("config_input", ""),
- ("config_microphone", ""),
- ("request_elevation_tip", ""),
- ("Wait", ""),
- ("Elevation Error", ""),
- ("Ask the remote user for authentication", ""),
- ("Choose this if the remote account is administrator", ""),
- ("Transmit the username and password of administrator", ""),
- ("still_click_uac_tip", ""),
- ("Request Elevation", ""),
- ("wait_accept_uac_tip", ""),
- ("Elevate successfully", ""),
- ("uppercase", ""),
- ("lowercase", ""),
- ("digit", ""),
- ("special character", ""),
- ("length>=8", ""),
- ("Weak", ""),
- ("Medium", ""),
- ("Strong", ""),
- ("Switch Sides", ""),
- ("Please confirm if you want to share your desktop?", ""),
- ("Display", ""),
- ("Default View Style", ""),
- ("Default Scroll Style", ""),
- ("Default Image Quality", ""),
- ("Default Codec", ""),
- ("Bitrate", ""),
- ("FPS", ""),
- ("Auto", ""),
- ("Other Default Options", ""),
- ("Voice call", ""),
- ("Text chat", ""),
- ("Stop voice call", ""),
- ("relay_hint_tip", ""),
- ("Reconnect", ""),
- ("Codec", ""),
- ("Resolution", ""),
- ("No transfers in progress", ""),
- ("Set one-time password length", ""),
- ("install_cert_tip", ""),
- ("confirm_install_cert_tip", ""),
- ("RDP Settings", ""),
- ("Sort by", ""),
- ("New Connection", ""),
- ("Restore", ""),
- ("Minimize", ""),
- ("Maximize", ""),
- ("Your Device", ""),
- ("empty_recent_tip", ""),
- ("empty_favorite_tip", ""),
- ("empty_lan_tip", ""),
- ("empty_address_book_tip", ""),
- ("eg: admin", ""),
- ("Empty Username", ""),
- ("Empty Password", ""),
- ("Me", ""),
- ("identical_file_tip", ""),
- ("show_monitors_tip", ""),
- ("View Mode", ""),
- ("login_linux_tip", ""),
- ("verify_rustdesk_password_tip", ""),
- ("remember_account_tip", ""),
- ("os_account_desk_tip", ""),
- ("OS Account", ""),
- ("another_user_login_title_tip", ""),
- ("another_user_login_text_tip", ""),
- ("xorg_not_found_title_tip", ""),
- ("xorg_not_found_text_tip", ""),
- ("no_desktop_title_tip", ""),
- ("no_desktop_text_tip", ""),
- ("No need to elevate", ""),
- ("System Sound", ""),
- ("Default", ""),
- ("New RDP", ""),
- ("Fingerprint", ""),
- ("Copy Fingerprint", ""),
- ("no fingerprints", ""),
- ("Select a peer", ""),
- ("Select peers", ""),
- ("Plugins", ""),
- ("Uninstall", ""),
- ("Update", ""),
- ("Enable", ""),
- ("Disable", ""),
- ("Options", ""),
- ("resolution_original_tip", ""),
- ("resolution_fit_local_tip", ""),
- ("resolution_custom_tip", ""),
- ("Collapse toolbar", ""),
- ("Accept and Elevate", ""),
- ("accept_and_elevate_btn_tooltip", ""),
- ("clipboard_wait_response_timeout_tip", ""),
- ("Incoming connection", ""),
- ("Outgoing connection", ""),
- ("Exit", ""),
- ("Open", ""),
- ("logout_tip", ""),
- ("Service", ""),
- ("Start", ""),
- ("Stop", ""),
- ("exceed_max_devices", ""),
- ("Sync with recent sessions", ""),
- ("Sort tags", ""),
- ("Open connection in new tab", ""),
- ("Move tab to new window", ""),
- ("Can not be empty", ""),
- ("Already exists", ""),
- ("Change Password", ""),
- ("Refresh Password", ""),
- ("ID", ""),
- ("Grid View", ""),
- ("List View", ""),
- ("Select", ""),
- ("Toggle Tags", ""),
- ("pull_ab_failed_tip", ""),
- ("push_ab_failed_tip", ""),
- ("synced_peer_readded_tip", ""),
- ("Change Color", ""),
- ("Primary Color", ""),
- ("HSV Color", ""),
+ ("hide_cm_tip", "Oturumları yalnızca parola ile kabul edebilir ve kalıcı parola kullanıyorsanız gizlemeye izin verin"),
+ ("wayland_experiment_tip", "Wayland desteği deneysel aşamada olduğundan, gerektiğinde X11'i kullanmanız önerilir"),
+ ("Right click to select tabs", "Sekmeleri seçmek için sağ tıklayın"),
+ ("Skipped", "Atlandı"),
+ ("Add to Address Book", "Adres Defterine Ekle"),
+ ("Group", "Grup"),
+ ("Search", "Ara"),
+ ("Closed manually by web console", "Web konsoluyla manuel olarak kapatıldı"),
+ ("Local keyboard type", "Yerel klavye türü"),
+ ("Select local keyboard type", "Yerel klavye türünü seçin"),
+ ("software_render_tip", "Linux altında Nvidia grafik kartı kullanıyorsanız ve uzak pencere bağlandıktan hemen sonra kapanıyorsa, açık kaynaklı Nouveau sürücüsüne geçmeyi ve yazılım renderleme seçeneğini seçmeyi deneyin. Yazılımı yeniden başlatmanız gerekebilir."),
+ ("Always use software rendering", "Her zaman yazılım renderleme kullan"),
+ ("config_input", "Uzaktaki masaüstünü klavye ile kontrol etmek için RustDesk'e \"Giriş İzleme\" izinleri vermelisiniz."),
+ ("config_microphone", "Uzaktan konuşmak için RustDesk'e \"Ses Kaydı\" izinleri vermelisiniz."),
+ ("request_elevation_tip", "Ayrıca, uzak tarafta biri varsa yükseltme isteğinde bulunabilirsiniz."),
+ ("Wait", "Bekle"),
+ ("Elevation Error", "Yükseltme Hatası"),
+ ("Ask the remote user for authentication", "Uzaktaki kullanıcıdan kimlik doğrulamasını isteyin"),
+ ("Choose this if the remote account is administrator", "Uzak hesap yönetici ise bunu seçin"),
+ ("Transmit the username and password of administrator", "Yönetici kullanıcı adı ve parolasını iletim yapın"),
+ ("still_click_uac_tip", "Uzaktaki kullanıcının çalışan RustDesk'in UAC penceresinde hala Tamam'ı tıklaması gerekmektedir."),
+ ("Request Elevation", "Yükseltme İsteği"),
+ ("wait_accept_uac_tip", "Lütfen uzaktaki kullanıcının UAC iletişim kutusunu kabul etmesini bekleyin."),
+ ("Elevate successfully", "Başarıyla yükseltildi"),
+ ("uppercase", "büyük harf"),
+ ("lowercase", "küçük harf"),
+ ("digit", "rakam"),
+ ("special character", "özel karakter"),
+ ("length>=8", "uzunluk>=8"),
+ ("Weak", "Zayıf"),
+ ("Medium", "Orta"),
+ ("Strong", "Güçlü"),
+ ("Switch Sides", "Tarafları Değiştir"),
+ ("Please confirm if you want to share your desktop?", "Masaüstünüzü paylaşmak isteyip istemediğinizi onaylayın?"),
+ ("Display", "Görüntüle"),
+ ("Default View Style", "Varsayılan Görünüm Stili"),
+ ("Default Scroll Style", "Varsayılan Kaydırma Stili"),
+ ("Default Image Quality", "Varsayılan Görüntü Kalitesi"),
+ ("Default Codec", "Varsayılan Kodlayıcı"),
+ ("Bitrate", "Bit Hızı"),
+ ("FPS", "FPS"),
+ ("Auto", "Otomatik"),
+ ("Other Default Options", "Diğer Varsayılan Seçenekler"),
+ ("Voice call", "Sesli görüşme"),
+ ("Text chat", "Metin sohbeti"),
+ ("Stop voice call", "Sesli görüşmeyi durdur"),
+ ("relay_hint_tip", "Doğrudan bağlanmak mümkün olmayabilir; röle aracılığıyla bağlanmayı deneyebilirsiniz. Ayrıca, ilk denemenizde bir röle kullanmak istiyorsanız, ID'nin sonuna \"/r\" ekleyebilir veya son oturum kartındaki \"Her Zaman Röle Üzerinden Bağlan\" seçeneğini seçebilirsiniz."),
+ ("Reconnect", "Yeniden Bağlan"),
+ ("Codec", "Kodlayıcı"),
+ ("Resolution", "Çözünürlük"),
+ ("No transfers in progress", "Devam eden aktarımlar yok"),
+ ("Set one-time password length", "Bir seferlik parola uzunluğunu ayarla"),
+ ("install_cert_tip", "RustDesk sertifikasını yükleyin"),
+ ("confirm_install_cert_tip", "Bu, güvenilir olabilecek bir RustDesk test sertifikasıdır. Sertifika, gerekli olduğunda RustDesk sürücülerini güvenilir ve yüklemek üzere kullanacaktır."),
+ ("RDP Settings", "RDP Ayarları"),
+ ("Sort by", "Sırala"),
+ ("New Connection", "Yeni Bağlantı"),
+ ("Restore", "Geri Yükle"),
+ ("Minimize", "Simge Durumuna Küçült"),
+ ("Maximize", "Büyüt"),
+ ("Your Device", "Cihazınız"),
+ ("empty_recent_tip", "Üzgünüz, henüz son oturum yok!\nYeni bir plan yapma zamanı."),
+ ("empty_favorite_tip", "Henüz favori cihazınız yok mu?\nBağlanacak ve favorilere eklemek için birini bulalım!"),
+ ("empty_lan_tip", "Hayır, henüz hiçbir cihaz bulamadık gibi görünüyor."),
+ ("empty_address_book_tip", "Üzgünüm, şu anda adres defterinizde kayıtlı cihaz yok gibi görünüyor."),
+ ("eg: admin", "örn: admin"),
+ ("Empty Username", "Boş Kullanıcı Adı"),
+ ("Empty Password", "Boş Parola"),
+ ("Me", "Ben"),
+ ("identical_file_tip", "Bu dosya, cihazın dosyası ile aynıdır."),
+ ("show_monitors_tip", "Monitörleri araç çubuğunda göster"),
+ ("View Mode", "Görünüm Modu"),
+ ("login_linux_tip", "X masaüstü oturumu başlatmak için uzaktaki Linux hesabına giriş yapmanız gerekiyor"),
+ ("verify_rustdesk_password_tip", "RustDesk parolasını doğrulayın"),
+ ("remember_account_tip", "Bu hesabı hatırla"),
+ ("os_account_desk_tip", "Bu hesap, uzaktaki işletim sistemine giriş yapmak ve başsız masaüstü oturumunu etkinleştirmek için kullanılır."),
+ ("OS Account", "İşletim Sistemi Hesabı"),
+ ("another_user_login_title_tip", "Başka bir kullanıcı zaten oturum açtı"),
+ ("another_user_login_text_tip", "Bağlantıyı Kapat"),
+ ("xorg_not_found_title_tip", "Xorg bulunamadı"),
+ ("xorg_not_found_text_tip", "Lütfen Xorg'u yükleyin"),
+ ("no_desktop_title_tip", "Masaüstü mevcut değil"),
+ ("no_desktop_text_tip", "Lütfen GNOME masaüstünü yükleyin"),
+ ("No need to elevate", "Yükseltmeye gerek yok"),
+ ("System Sound", "Sistem Ses"),
+ ("Default", "Varsayılan"),
+ ("New RDP", "Yeni RDP"),
+ ("Fingerprint", "Parmak İzi"),
+ ("Copy Fingerprint", "Parmak İzini Kopyala"),
+ ("no fingerprints", "parmak izi yok"),
+ ("Select a peer", "Bir cihaz seçin"),
+ ("Select peers", "Cihazları seçin"),
+ ("Plugins", "Eklentiler"),
+ ("Uninstall", "Kaldır"),
+ ("Update", "Güncelle"),
+ ("Enable", "Etkinleştir"),
+ ("Disable", "Devre Dışı Bırak"),
+ ("Options", "Seçenekler"),
+ ("resolution_original_tip", "Orijinal çözünürlük"),
+ ("resolution_fit_local_tip", "Yerel çözünürlüğe sığdır"),
+ ("resolution_custom_tip", "Özel çözünürlük"),
+ ("Collapse toolbar", "Araç çubuğunu daralt"),
+ ("Accept and Elevate", "Kabul et ve yükselt"),
+ ("accept_and_elevate_btn_tooltip", "Bağlantıyı kabul et ve UAC izinlerini yükselt."),
+ ("clipboard_wait_response_timeout_tip", "Kopyalama yanıtı için zaman aşımına uğradı."),
+ ("Incoming connection", "Gelen bağlantı"),
+ ("Outgoing connection", "Giden bağlantı"),
+ ("Exit", "Çıkış"),
+ ("Open", "Aç"),
+ ("logout_tip", "Çıkış yapmak istediğinizden emin misiniz?"),
+ ("Service", "Hizmet"),
+ ("Start", "Başlat"),
+ ("Stop", "Durdur"),
+ ("exceed_max_devices", "Yönetilen cihazların maksimum sayısına ulaştınız."),
+ ("Sync with recent sessions", "Son oturumlarla senkronize et"),
+ ("Sort tags", "Etiketleri sırala"),
+ ("Open connection in new tab", "Bağlantıyı yeni sekmede aç"),
+ ("Move tab to new window", "Sekmeyi yeni pencereye taşı"),
+ ("Can not be empty", "Boş olamaz"),
+ ("Already exists", "Zaten var"),
+ ("Change Password", "Parolayı Değiştir"),
+ ("Refresh Password", "Parolayı Yenile"),
+ ("ID", "Kimlik"),
+ ("Grid View", "Izgara Görünümü"),
+ ("List View", "Liste Görünümü"),
+ ("Select", "Seç"),
+ ("Toggle Tags", "Etiketleri Değiştir"),
+ ("pull_ab_failed_tip", "Adres defterini yenileyemedi"),
+ ("push_ab_failed_tip", "Adres defterini sunucuya senkronize edemedi"),
+ ("synced_peer_readded_tip", "Son oturumlar listesinde bulunan cihazlar adres defterine geri senkronize edilecektir."),
+ ("Change Color", "Rengi Değiştir"),
+ ("Primary Color", "Birincil Renk"),
+ ("HSV Color", "HSV Rengi"),
].iter().cloned().collect();
}
From 3f12a172469c31beac499b795ec427ce61744cd9 Mon Sep 17 00:00:00 2001
From: RustDesk <71636191+rustdesk@users.noreply.github.com>
Date: Fri, 25 Aug 2023 21:43:32 +0800
Subject: [PATCH 72/75] TR
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 26efb3559..5cf17bf4d 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [Українська ] | [česky ] | [中文 ] | [Magyar ] | [Español ] | [فارسی ] | [Français ] | [Deutsch ] | [Polski ] | [Indonesian ] | [Suomi ] | [മലയാളം ] | [日本語 ] | [Nederlands ] | [Italiano ] | [Русский ] | [Português (Brasil) ] | [Esperanto ] | [한국어 ] | [العربي ] | [Tiếng Việt ] | [Dansk ] | [Ελληνικά ]
+ [Українська ] | [česky ] | [中文 ] | [Magyar ] | [Español ] | [فارسی ] | [Français ] | [Deutsch ] | [Polski ] | [Indonesian ] | [Suomi ] | [മലയാളം ] | [日本語 ] | [Nederlands ] | [Italiano ] | [Русский ] | [Português (Brasil) ] | [Esperanto ] | [한국어 ] | [العربي ] | [Tiếng Việt ] | [Dansk ] | [Ελληνικά ] | [Türkçe ]
We need your help to translate this README, RustDesk UI and RustDesk Doc to your native language
From 8fea5585e520d75d0a50cac17629279964d65b52 Mon Sep 17 00:00:00 2001
From: RustDesk <71636191+rustdesk@users.noreply.github.com>
Date: Fri, 25 Aug 2023 21:45:00 +0800
Subject: [PATCH 73/75] Update README-TR.md
---
docs/README-TR.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/README-TR.md b/docs/README-TR.md
index fa1f79c37..590ead0df 100644
--- a/docs/README-TR.md
+++ b/docs/README-TR.md
@@ -1,6 +1,6 @@
-
+
Sunucular •
Derleme •
Docker ile Derleme •
From 3e6faf83643c74272534f9bb04c0a2f4e2cbe9f0 Mon Sep 17 00:00:00 2001
From: 21pages
Date: Sat, 26 Aug 2023 10:05:25 +0800
Subject: [PATCH 74/75] rust start cm ipc only after login request permission
check or switch sides
Signed-off-by: 21pages
---
src/server/connection.rs | 48 +++++++++++++++++++++++++++++++++-------
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/src/server/connection.rs b/src/server/connection.rs
index 7d1768f4c..22459096f 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -135,6 +135,14 @@ struct Session {
random_password: String,
}
+#[cfg(not(any(target_os = "android", target_os = "ios")))]
+struct StartCmIpcPara {
+ rx_to_cm: mpsc::UnboundedReceiver,
+ tx_from_cm: mpsc::UnboundedSender,
+ rx_desktop_ready: mpsc::Receiver<()>,
+ tx_cm_stream_ready: mpsc::Sender<()>,
+}
+
pub struct Connection {
inner: ConnInner,
stream: super::Stream,
@@ -193,6 +201,8 @@ pub struct Connection {
linux_headless_handle: LinuxHeadlessHandle,
closed: bool,
delay_response_instant: Instant,
+ #[cfg(not(any(target_os = "android", target_os = "ios")))]
+ start_cm_ipc_para: Option,
}
impl ConnInner {
@@ -324,6 +334,13 @@ impl Connection {
linux_headless_handle,
closed: false,
delay_response_instant: Instant::now(),
+ #[cfg(not(any(target_os = "android", target_os = "ios")))]
+ start_cm_ipc_para: Some(StartCmIpcPara {
+ rx_to_cm,
+ tx_from_cm,
+ rx_desktop_ready,
+ tx_cm_stream_ready,
+ }),
};
let addr = hbb_common::try_into_v4(addr);
if !conn.on_open(addr).await {
@@ -332,14 +349,6 @@ impl Connection {
sleep(1.).await;
return;
}
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- tokio::spawn(async move {
- if let Err(err) =
- start_ipc(rx_to_cm, tx_from_cm, rx_desktop_ready, tx_cm_stream_ready).await
- {
- log::error!("ipc to connection manager exit: {}", err);
- }
- });
#[cfg(target_os = "android")]
start_channel(rx_to_cm, tx_from_cm);
if !conn.keyboard {
@@ -1316,6 +1325,24 @@ impl Connection {
self.video_ack_required = lr.video_ack_required;
}
+ #[cfg(not(any(target_os = "android", target_os = "ios")))]
+ fn try_start_cm_ipc(&mut self) {
+ if let Some(p) = self.start_cm_ipc_para.take() {
+ tokio::spawn(async move {
+ if let Err(err) = start_ipc(
+ p.rx_to_cm,
+ p.tx_from_cm,
+ p.rx_desktop_ready,
+ p.tx_cm_stream_ready,
+ )
+ .await
+ {
+ log::error!("ipc to connection manager exit: {}", err);
+ }
+ });
+ }
+ }
+
async fn on_message(&mut self, msg: Message) -> bool {
if let Some(message::Union::LoginRequest(lr)) = msg.union {
self.handle_login_request_without_validation(&lr).await;
@@ -1379,6 +1406,9 @@ impl Connection {
}
}
+ #[cfg(not(any(target_os = "android", target_os = "ios")))]
+ self.try_start_cm_ipc();
+
#[cfg(any(
feature = "flatpak",
feature = "appimage",
@@ -1543,6 +1573,8 @@ impl Connection {
self.from_switch = true;
self.try_start_cm(lr.my_id.clone(), lr.my_name.clone(), true);
self.send_logon_response().await;
+ #[cfg(not(any(target_os = "android", target_os = "ios")))]
+ self.try_start_cm_ipc();
}
}
}
From 50b8744f244867a57008bb5805ac8f51851dcef6 Mon Sep 17 00:00:00 2001
From: 21pages
Date: Sat, 26 Aug 2023 18:49:23 +0800
Subject: [PATCH 75/75] flutter hide cm if client is empty, close cm if that
last for 6 seconds
Signed-off-by: 21pages
---
flutter/lib/main.dart | 10 ++++---
flutter/lib/models/server_model.dart | 40 ++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart
index dbf563de2..8edd3a356 100644
--- a/flutter/lib/main.dart
+++ b/flutter/lib/main.dart
@@ -268,10 +268,12 @@ hideCmWindow({bool isStartup = false}) async {
await windowManager.hide();
});
} else {
- await windowManager.setOpacity(0);
- bind.mainHideDocker();
- await windowManager.minimize();
- await windowManager.hide();
+ if (await windowManager.getOpacity() != 0) {
+ await windowManager.setOpacity(0);
+ bind.mainHideDocker();
+ await windowManager.minimize();
+ await windowManager.hide();
+ }
}
}
diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart
index 8f56ffbe2..716c535ad 100644
--- a/flutter/lib/models/server_model.dart
+++ b/flutter/lib/models/server_model.dart
@@ -36,6 +36,7 @@ class ServerModel with ChangeNotifier {
String _verificationMethod = "";
String _temporaryPasswordLength = "";
String _approveMode = "";
+ int _zeroClientLengthCounter = 0;
late String _emptyIdShow;
late final IDTextEditingController _serverId;
@@ -120,6 +121,17 @@ class ServerModel with ChangeNotifier {
_emptyIdShow = translate("Generating ...");
_serverId = IDTextEditingController(text: _emptyIdShow);
+ // initital _hideCm at startup
+ final verificationMethod =
+ bind.mainGetOptionSync(key: "verification-method");
+ final approveMode = bind.mainGetOptionSync(key: 'approve-mode');
+ _hideCm = option2bool(
+ 'allow-hide-cm', bind.mainGetOptionSync(key: 'allow-hide-cm'));
+ if (!(approveMode == 'password' &&
+ verificationMethod == kUsePermanentPassword)) {
+ _hideCm = false;
+ }
+
timerCallback() async {
final connectionStatus =
jsonDecode(await bind.mainGetConnectStatus()) as Map;
@@ -134,6 +146,17 @@ class ServerModel with ChangeNotifier {
if (res != null) {
debugPrint("clients not match!");
updateClientState(res);
+ } else {
+ if (_clients.isEmpty) {
+ hideCmWindow();
+ if (_zeroClientLengthCounter++ == 12) {
+ // 6 second
+ windowManager.close();
+ }
+ } else {
+ _zeroClientLengthCounter = 0;
+ if (!_hideCm) showCmWindow();
+ }
}
}
@@ -422,6 +445,7 @@ class ServerModel with ChangeNotifier {
return;
}
+ final oldClientLenght = _clients.length;
_clients.clear();
tabController.state.value.tabs.clear();
@@ -434,6 +458,16 @@ class ServerModel with ChangeNotifier {
debugPrint("Failed to decode clientJson '$clientJson', error $e");
}
}
+ if (desktopType == DesktopType.cm) {
+ if (_clients.isEmpty) {
+ hideCmWindow();
+ } else if (!_hideCm) {
+ showCmWindow();
+ }
+ }
+ if (_clients.length != oldClientLenght) {
+ notifyListeners();
+ }
}
void addConnection(Map evt) {
@@ -461,6 +495,9 @@ class ServerModel with ChangeNotifier {
_clients.removeAt(index_disconnected);
tabController.remove(index_disconnected);
}
+ if (desktopType == DesktopType.cm && !_hideCm) {
+ showCmWindow();
+ }
scrollToBottom();
notifyListeners();
if (isAndroid && !client.authorized) showLoginDialog(client);
@@ -581,6 +618,9 @@ class ServerModel with ChangeNotifier {
parent.target?.dialogManager.dismissByTag(getLoginDialogTag(id));
parent.target?.invokeMethod("cancel_notification", id);
}
+ if (desktopType == DesktopType.cm && _clients.isEmpty) {
+ hideCmWindow();
+ }
notifyListeners();
} catch (e) {
debugPrint("onClientRemove failed,error:$e");