auto disconnect

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2023-09-13 13:45:40 +08:00
parent 75f5212661
commit 0a0653358c
40 changed files with 308 additions and 2 deletions

View File

@ -302,6 +302,53 @@ Future<String> changeDirectAccessPort(
return controller.text; return controller.text;
} }
Future<String> changeAutoDisconnectTimeout(String old) async {
final controller = TextEditingController(text: old);
await gFFI.dialogManager.show((setState, close, context) {
return CustomAlertDialog(
title: Text(translate("Timeout in minutes")),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 8.0),
Row(
children: [
Expanded(
child: TextField(
maxLines: null,
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: '10',
isCollapsed: true,
suffix: IconButton(
padding: EdgeInsets.zero,
icon: const Icon(Icons.clear, size: 16),
onPressed: () => controller.clear())),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(
r'^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$')),
],
controller: controller,
autofocus: true),
),
],
),
],
),
actions: [
dialogButton("Cancel", onPressed: close, isOutline: true),
dialogButton("OK", onPressed: () async {
await bind.mainSetOption(
key: 'auto-disconnect-timeout', value: controller.text);
close();
}),
],
onCancel: close,
);
});
return controller.text;
}
class DialogTextField extends StatelessWidget { class DialogTextField extends StatelessWidget {
final String title; final String title;
final String? hintText; final String? hintText;

View File

@ -728,6 +728,7 @@ class _SafetyState extends State<_Safety> with AutomaticKeepAliveClientMixin {
reverse: true, enabled: enabled), reverse: true, enabled: enabled),
...directIp(context), ...directIp(context),
whitelist(), whitelist(),
...autoDisconnect(context),
]); ]);
} }
@ -906,6 +907,63 @@ class _SafetyState extends State<_Safety> with AutomaticKeepAliveClientMixin {
)); ));
})); }));
} }
List<Widget> autoDisconnect(BuildContext context) {
TextEditingController controller = TextEditingController();
update() => setState(() {});
RxBool applyEnabled = false.obs;
final optionKey = 'allow-auto-disconnect';
final timeoutKey = 'auto-disconnect-timeout';
return [
_OptionCheckBox(context, 'auto_disconnect_option_tip', optionKey,
update: update, enabled: !locked),
() {
bool enabled =
option2bool(optionKey, bind.mainGetOptionSync(key: optionKey));
if (!enabled) applyEnabled.value = false;
controller.text = bind.mainGetOptionSync(key: timeoutKey);
return Offstage(
offstage: !enabled,
child: _SubLabeledWidget(
context,
'Timeout in minutes',
Row(children: [
SizedBox(
width: 95,
child: TextField(
controller: controller,
enabled: enabled && !locked,
onChanged: (_) => applyEnabled.value = true,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(
r'^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$')),
],
decoration: const InputDecoration(
hintText: '10',
contentPadding:
EdgeInsets.symmetric(vertical: 12, horizontal: 12),
),
).marginOnly(right: 15),
),
Obx(() => ElevatedButton(
onPressed: applyEnabled.value && enabled && !locked
? () async {
applyEnabled.value = false;
await bind.mainSetOption(
key: timeoutKey, value: controller.text);
}
: null,
child: Text(
translate('Apply'),
),
))
]),
enabled: enabled && !locked,
),
);
}(),
];
}
} }
class _Network extends StatefulWidget { class _Network extends StatefulWidget {

View File

@ -45,10 +45,12 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
var _enableDirectIPAccess = false; var _enableDirectIPAccess = false;
var _enableRecordSession = false; var _enableRecordSession = false;
var _autoRecordIncomingSession = false; var _autoRecordIncomingSession = false;
var _allowAutoDisconnect = false;
var _localIP = ""; var _localIP = "";
var _directAccessPort = ""; var _directAccessPort = "";
var _fingerprint = ""; var _fingerprint = "";
var _buildDate = ""; var _buildDate = "";
var _autoDisconnectTimeout = "";
@override @override
void initState() { void initState() {
@ -151,6 +153,20 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
_buildDate = buildDate; _buildDate = buildDate;
} }
final allowAutoDisconnect = option2bool('allow-auto-disconnect',
await bind.mainGetOption(key: 'allow-auto-disconnect'));
if (allowAutoDisconnect != _allowAutoDisconnect) {
update = true;
_allowAutoDisconnect = allowAutoDisconnect;
}
final autoDisconnectTimeout =
await bind.mainGetOption(key: 'auto-disconnect-timeout');
if (autoDisconnectTimeout != _autoDisconnectTimeout) {
update = true;
_autoDisconnectTimeout = autoDisconnectTimeout;
}
if (update) { if (update) {
setState(() {}); setState(() {});
} }
@ -306,6 +322,48 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
await bind.mainSetOption(key: 'direct-server', value: value); await bind.mainSetOption(key: 'direct-server', value: value);
setState(() {}); setState(() {});
}, },
),
SettingsTile.switchTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(translate("auto_disconnect_option_tip")),
Offstage(
offstage: !_allowAutoDisconnect,
child: Text(
'${_autoDisconnectTimeout.isEmpty ? '10' : _autoDisconnectTimeout} min',
style: Theme.of(context).textTheme.bodySmall,
)),
])),
Offstage(
offstage: !_allowAutoDisconnect,
child: IconButton(
padding: EdgeInsets.zero,
icon: Icon(
Icons.edit,
size: 20,
),
onPressed: () async {
final timeout = await changeAutoDisconnectTimeout(
_autoDisconnectTimeout);
setState(() {
_autoDisconnectTimeout = timeout;
});
}))
]),
initialValue: _allowAutoDisconnect,
onToggle: (_) async {
_allowAutoDisconnect = !_allowAutoDisconnect;
String value =
bool2option('allow-auto-disconnect', _allowAutoDisconnect);
await bind.mainSetOption(key: 'allow-auto-disconnect', value: value);
setState(() {});
},
) )
]; ];
if (_hasIgnoreBattery) { if (_hasIgnoreBattery) {

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", "超时(分钟)"),
("auto_disconnect_option_tip", "自动关闭不活跃的会话"),
("Connection failed due to inactivity", "由于长时间无操作, 连接被自动断开"),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -88,5 +88,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", "Don't show again"), ("Don't show again", "Don't show again"),
("I Agree", "I Agree"), ("I Agree", "I Agree"),
("Decline", "Decline"), ("Decline", "Decline"),
("auto_disconnect_option_tip", "Automatically close incoming sessions on user inactivity"),
("Connection failed due to inactivity", "Automatically disconnected due to inactivity"),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -549,7 +549,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("scam_text1", ""), ("scam_text1", ""),
("scam_text2", ""), ("scam_text2", ""),
("Don't show again", ""), ("Don't show again", ""),
("I Agree",""), ("I Agree", ""),
("Decline",""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -551,5 +551,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Don't show again", ""), ("Don't show again", ""),
("I Agree", ""), ("I Agree", ""),
("Decline", ""), ("Decline", ""),
("Timeout in minutes", ""),
("auto_disconnect_option_tip", ""),
("Connection failed due to inactivity", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -204,6 +204,7 @@ pub struct Connection {
delay_response_instant: Instant, delay_response_instant: Instant,
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
start_cm_ipc_para: Option<StartCmIpcPara>, start_cm_ipc_para: Option<StartCmIpcPara>,
auto_disconnect_timer: Option<(Instant, u64)>,
} }
impl ConnInner { impl ConnInner {
@ -343,6 +344,7 @@ impl Connection {
rx_desktop_ready, rx_desktop_ready,
tx_cm_stream_ready, tx_cm_stream_ready,
}), }),
auto_disconnect_timer: None,
}; };
let addr = hbb_common::try_into_v4(addr); let addr = hbb_common::try_into_v4(addr);
if !conn.on_open(addr).await { if !conn.on_open(addr).await {
@ -605,6 +607,13 @@ impl Connection {
_ = second_timer.tick() => { _ = second_timer.tick() => {
#[cfg(windows)] #[cfg(windows)]
conn.portable_check(); conn.portable_check();
if let Some((instant, minute)) = conn.auto_disconnect_timer.as_ref() {
if instant.elapsed().as_secs() > minute * 60 {
conn.send_close_reason_no_retry("Connection failed due to inactivity").await;
conn.on_close("auto disconnect", true).await;
break;
}
}
} }
_ = test_delay_timer.tick() => { _ = test_delay_timer.tick() => {
if last_recv_time.elapsed() >= SEC30 { if last_recv_time.elapsed() >= SEC30 {
@ -1139,6 +1148,7 @@ impl Connection {
let mut s = s.write().unwrap(); let mut s = s.write().unwrap();
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
let _h = try_start_record_cursor_pos(); let _h = try_start_record_cursor_pos();
self.auto_disconnect_timer = Self::get_auto_disconenct_timer();
s.add_connection(self.inner.clone(), &noperms); s.add_connection(self.inner.clone(), &noperms);
} }
} }
@ -1612,6 +1622,7 @@ impl Connection {
} }
self.input_mouse(me, self.inner.id()); self.input_mouse(me, self.inner.id());
} }
self.update_auto_disconnect_timer();
} }
Some(message::Union::PointerDeviceEvent(pde)) => { Some(message::Union::PointerDeviceEvent(pde)) => {
#[cfg(any(target_os = "android", target_os = "ios"))] #[cfg(any(target_os = "android", target_os = "ios"))]
@ -1647,6 +1658,7 @@ impl Connection {
MOUSE_MOVE_TIME.store(get_time(), Ordering::SeqCst); MOUSE_MOVE_TIME.store(get_time(), Ordering::SeqCst);
self.input_pointer(pde, self.inner.id()); self.input_pointer(pde, self.inner.id());
} }
self.update_auto_disconnect_timer();
} }
#[cfg(any(target_os = "android", target_os = "ios"))] #[cfg(any(target_os = "android", target_os = "ios"))]
Some(message::Union::KeyEvent(..)) => {} Some(message::Union::KeyEvent(..)) => {}
@ -1702,6 +1714,7 @@ impl Connection {
self.input_key(me, false); self.input_key(me, false);
} }
} }
self.update_auto_disconnect_timer();
} }
Some(message::Union::Clipboard(_cb)) => Some(message::Union::Clipboard(_cb)) =>
{ {
@ -1890,6 +1903,7 @@ impl Connection {
Some(misc::Union::ChatMessage(c)) => { Some(misc::Union::ChatMessage(c)) => {
self.send_to_cm(ipc::Data::ChatMessage { text: c.text }); self.send_to_cm(ipc::Data::ChatMessage { text: c.text });
self.chat_unanswered = true; self.chat_unanswered = true;
self.update_auto_disconnect_timer();
} }
Some(misc::Union::Option(o)) => { Some(misc::Union::Option(o)) => {
self.update_options(&o).await; self.update_options(&o).await;
@ -1898,6 +1912,7 @@ impl Connection {
if r { if r {
super::video_service::refresh(); super::video_service::refresh();
} }
self.update_auto_disconnect_timer();
} }
Some(misc::Union::VideoReceived(_)) => { Some(misc::Union::VideoReceived(_)) => {
video_service::notify_video_frame_fetched( video_service::notify_video_frame_fetched(
@ -2027,6 +2042,7 @@ impl Connection {
let mut msg = Message::new(); let mut msg = Message::new();
msg.set_misc(misc); msg.set_misc(misc);
self.send(msg).await; self.send(msg).await;
self.update_auto_disconnect_timer();
} }
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
@ -2384,6 +2400,26 @@ impl Connection {
} }
self.pressed_modifiers.clear(); self.pressed_modifiers.clear();
} }
fn get_auto_disconenct_timer() -> Option<(Instant, u64)> {
if Config::get_option("allow-auto-disconnect") == "Y" {
let mut minute: u64 = Config::get_option("auto-disconnect-timeout")
.parse()
.unwrap_or(10);
if minute == 0 {
minute = 10;
}
Some((Instant::now(), minute))
} else {
None
}
}
fn update_auto_disconnect_timer(&mut self) {
self.auto_disconnect_timer
.as_mut()
.map(|t| t.0 = Instant::now());
}
} }
pub fn insert_switch_sides_uuid(id: String, uuid: uuid::Uuid) { pub fn insert_switch_sides_uuid(id: String, uuid: uuid::Uuid) {