terminal works basically. (#12189)

* terminal works basically.
todo:
- persistent
- sessions restore
- web
- mobile

* missed terminal persistent option change

* android sdk 34 -> 35

* +#![cfg_attr(lt_1_77, feature(c_str_literals))]

* fixing ci

* fix ci

* fix ci for android

* try "Fix Android SDK Platform 35"

* fix android 34

* revert flutter_plugin_android_lifecycle to 2.0.17 which used in rustdesk 1.4.0

* refactor, but break something of desktop terminal (new tab showing loading)

* fix connecting...
This commit is contained in:
RustDesk
2025-07-01 13:12:55 +08:00
committed by GitHub
parent ee5cdc3155
commit 5faf0ad3cf
130 changed files with 4064 additions and 4247 deletions

View File

@@ -491,6 +491,7 @@ abstract class BasePeerCard extends StatelessWidget {
bool isViewCamera = false,
bool isTcpTunneling = false,
bool isRDP = false,
bool isTerminal = false,
}) {
return MenuEntryButton<String>(
childBuilder: (TextStyle? style) => Text(
@@ -506,6 +507,7 @@ abstract class BasePeerCard extends StatelessWidget {
isViewCamera: isViewCamera,
isTcpTunneling: isTcpTunneling,
isRDP: isRDP,
isTerminal: isTerminal,
);
},
padding: menuPadding,
@@ -541,6 +543,15 @@ abstract class BasePeerCard extends StatelessWidget {
);
}
@protected
MenuEntryBase<String> _terminalAction(BuildContext context) {
return _connectCommonAction(
context,
translate('Terminal'),
isTerminal: true,
);
}
@protected
MenuEntryBase<String> _tcpTunnelingAction(BuildContext context) {
return _connectCommonAction(
@@ -892,6 +903,7 @@ class RecentPeerCard extends BasePeerCard {
_connectAction(context),
_transferFileAction(context),
_viewCameraAction(context),
_terminalAction(context),
];
final List favs = (await bind.mainGetFav()).toList();
@@ -952,6 +964,7 @@ class FavoritePeerCard extends BasePeerCard {
_connectAction(context),
_transferFileAction(context),
_viewCameraAction(context),
_terminalAction(context),
];
if (isDesktop && peer.platform != kPeerPlatformAndroid) {
menuItems.add(_tcpTunnelingAction(context));
@@ -1006,6 +1019,7 @@ class DiscoveredPeerCard extends BasePeerCard {
_connectAction(context),
_transferFileAction(context),
_viewCameraAction(context),
_terminalAction(context),
];
final List favs = (await bind.mainGetFav()).toList();
@@ -1060,6 +1074,7 @@ class AddressBookPeerCard extends BasePeerCard {
_connectAction(context),
_transferFileAction(context),
_viewCameraAction(context),
_terminalAction(context),
];
if (isDesktop && peer.platform != kPeerPlatformAndroid) {
menuItems.add(_tcpTunnelingAction(context));
@@ -1195,6 +1210,7 @@ class MyGroupPeerCard extends BasePeerCard {
_connectAction(context),
_transferFileAction(context),
_viewCameraAction(context),
_terminalAction(context),
];
if (isDesktop && peer.platform != kPeerPlatformAndroid) {
menuItems.add(_tcpTunnelingAction(context));
@@ -1420,7 +1436,8 @@ void connectInPeerTab(BuildContext context, Peer peer, PeerTabIndex tab,
{bool isFileTransfer = false,
bool isViewCamera = false,
bool isTcpTunneling = false,
bool isRDP = false}) async {
bool isRDP = false,
bool isTerminal = false}) async {
var password = '';
bool isSharedPassword = false;
if (tab == PeerTabIndex.ab) {
@@ -1444,6 +1461,7 @@ void connectInPeerTab(BuildContext context, Peer peer, PeerTabIndex tab,
password: password,
isSharedPassword: isSharedPassword,
isFileTransfer: isFileTransfer,
isTerminal: isTerminal,
isViewCamera: isViewCamera,
isTcpTunneling: isTcpTunneling,
isRDP: isRDP);

View File

@@ -243,7 +243,8 @@ List<(String, String)> otherDefaultSettings() {
(
'Use all my displays for the remote session',
kKeyUseAllMyDisplaysForTheRemoteSession
)
),
('Keep terminal sessions on disconnect', kOptionTerminalPersistent),
];
return v;

View File

@@ -154,36 +154,38 @@ List<TTextMenu> toolbarControls(BuildContext context, String id, FFI ffi) {
onPressed: () => ffi.cursorModel.reset()));
}
// https://github.com/rustdesk/rustdesk/pull/9731
// Does not work for connection established by "accept".
connectWithToken(
{bool isFileTransfer = false,
bool isViewCamera = false,
bool isTcpTunneling = false}) {
bool isTcpTunneling = false,
bool isTerminal = false}) {
final connToken = bind.sessionGetConnToken(sessionId: ffi.sessionId);
connect(context, id,
isFileTransfer: isFileTransfer,
isViewCamera: isViewCamera,
isTerminal: isTerminal,
isTcpTunneling: isTcpTunneling,
connToken: connToken);
}
// transferFile
if (isDefaultConn && isDesktop) {
v.add(
TTextMenu(
child: Text(translate('Transfer file')),
onPressed: () => connectWithToken(isFileTransfer: true)),
);
}
// viewCamera
if (isDefaultConn && isDesktop) {
v.add(
TTextMenu(
child: Text(translate('View camera')),
onPressed: () => connectWithToken(isViewCamera: true)),
);
}
// tcpTunneling
if (isDefaultConn && isDesktop) {
v.add(
TTextMenu(
child: Text(translate('Terminal')),
onPressed: () => connectWithToken(isTerminal: true)),
);
v.add(
TTextMenu(
child: Text(translate('TCP tunneling')),