Merge pull request #5288 from dignow/feat/open_conn_opts

Feat/open conn opts
This commit is contained in:
RustDesk 2023-08-08 14:39:26 +08:00 committed by GitHub
commit d91d87b67f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 114 additions and 134 deletions

View File

@ -1240,7 +1240,7 @@ bool option2bool(String option, String value) {
option == "stop-service" ||
option == "direct-server" ||
option == "stop-rendezvous-service" ||
option == "force-always-relay") {
option == kOptionForceAlwaysRelay) {
res = value == "Y";
} else {
assert(false);
@ -1257,7 +1257,7 @@ String bool2option(String option, bool b) {
option == "stop-service" ||
option == "direct-server" ||
option == "stop-rendezvous-service" ||
option == "force-always-relay") {
option == kOptionForceAlwaysRelay) {
res = b ? 'Y' : '';
} else {
assert(false);
@ -1288,6 +1288,14 @@ bool mainGetLocalBoolOptionSync(String key) {
return option2bool(key, bind.mainGetLocalOption(key: key));
}
bool mainGetPeerBoolOptionSync(String id, String key) {
return option2bool(key, bind.mainGetPeerOptionSync(id: id, key: key));
}
mainSetPeerBoolOptionSync(String id, String key, bool v) {
bind.mainSetPeerOptionSync(id: id, key: key, value: bool2option(key, v));
}
Future<bool> matchPeer(String searchText, Peer peer) async {
if (searchText.isEmpty) {
return true;
@ -1545,7 +1553,9 @@ Future<bool> restoreWindowPosition(WindowType type,
debugPrint("no window position saved, ignoring position restoration");
return false;
}
if (type == WindowType.RemoteDesktop && !isRemotePeerPos && windowId != null) {
if (type == WindowType.RemoteDesktop &&
!isRemotePeerPos &&
windowId != null) {
if (lpos.offsetWidth != null) {
lpos.offsetWidth = lpos.offsetWidth! + windowId * 20;
}
@ -1801,14 +1811,13 @@ connectMainDesktop(
required bool isTcpTunneling,
required bool isRDP,
bool? forceRelay,
bool forceSeparateWindow = false,
}) async {
if (isFileTransfer) {
await rustDeskWinManager.newFileTransfer(id, forceRelay: forceRelay);
} else if (isTcpTunneling || isRDP) {
await rustDeskWinManager.newPortForward(id, isRDP, forceRelay: forceRelay);
} else {
await rustDeskWinManager.newRemoteDesktop(id, forceRelay: forceRelay, forceSeparateWindow: forceSeparateWindow);
await rustDeskWinManager.newRemoteDesktop(id, forceRelay: forceRelay);
}
}
@ -1822,7 +1831,6 @@ connect(
bool isFileTransfer = false,
bool isTcpTunneling = false,
bool isRDP = false,
bool forceSeparateWindow = false,
}) async {
if (id == '') return;
id = id.replaceAll(' ', '');
@ -1840,7 +1848,6 @@ connect(
isTcpTunneling: isTcpTunneling,
isRDP: isRDP,
forceRelay: forceRelay,
forceSeparateWindow: forceSeparateWindow,
);
} else {
await rustDeskWinManager.call(WindowType.Main, kWindowConnect, {
@ -1849,7 +1856,6 @@ connect(
'isTcpTunneling': isTcpTunneling,
'isRDP': isRDP,
'forceRelay': forceRelay,
'forceSeparateWindow': forceSeparateWindow,
});
}
} else {

View File

@ -404,7 +404,6 @@ abstract class BasePeerCard extends StatelessWidget {
bool isFileTransfer = false,
bool isTcpTunneling = false,
bool isRDP = false,
bool forceSeparateWindow = false,
}) {
return MenuEntryButton<String>(
childBuilder: (TextStyle? style) => Text(
@ -418,7 +417,6 @@ abstract class BasePeerCard extends StatelessWidget {
isFileTransfer: isFileTransfer,
isTcpTunneling: isTcpTunneling,
isRDP: isRDP,
forceSeparateWindow: forceSeparateWindow,
);
},
padding: menuPadding,
@ -427,25 +425,13 @@ abstract class BasePeerCard extends StatelessWidget {
}
@protected
List<MenuEntryBase<String>> _connectActions(BuildContext context, Peer peer) {
final actions = [_connectAction(context, peer, false)];
if (!mainGetLocalBoolOptionSync(kOptionSeparateRemoteWindow)) {
actions.add(_connectAction(context, peer, true));
}
return actions;
}
@protected
MenuEntryBase<String> _connectAction(
BuildContext context, Peer peer, bool forceSeparateWindow) {
MenuEntryBase<String> _connectAction(BuildContext context, Peer peer) {
return _connectCommonAction(
context,
peer.id,
(peer.alias.isEmpty
? translate('Connect')
: '${translate('Connect')} ${peer.id}') +
(forceSeparateWindow ? ' (${translate('separate window')})' : ''),
forceSeparateWindow: forceSeparateWindow,
? translate('Connect')
: '${translate('Connect')} ${peer.id}'),
);
}
@ -538,15 +524,40 @@ abstract class BasePeerCard extends StatelessWidget {
);
}
Future<MenuEntryBase<String>> _openNewConnInAction(
String id, String label, String key) async {
return MenuEntrySwitch<String>(
switchType: SwitchType.scheckbox,
text: translate(label),
getter: () async => mainGetPeerBoolOptionSync(id, key),
setter: (bool v) async {
await bind.mainSetPeerOption(
id: id, key: key, value: bool2option(key, v));
},
padding: menuPadding,
dismissOnClicked: true,
);
}
_openInTabsAction(String id) async =>
await _openNewConnInAction(id, 'Open in Tabs', kOptionOpenInTabs);
_openInWindowsAction(String id) async =>
await _openNewConnInAction(id, 'Open with New Window', kOptionOpenInWindows);
_openNewConnInOptAction(String id) async =>
mainGetLocalBoolOptionSync(kOptionOpenNewConnInTabs)
? await _openInWindowsAction(id)
: await _openInTabsAction(id);
@protected
Future<bool> _isForceAlwaysRelay(String id) async {
return (await bind.mainGetPeerOption(id: id, key: 'force-always-relay'))
return (await bind.mainGetPeerOption(id: id, key: kOptionForceAlwaysRelay))
.isNotEmpty;
}
@protected
Future<MenuEntryBase<String>> _forceAlwaysRelayAction(String id) async {
const option = 'force-always-relay';
return MenuEntrySwitch<String>(
switchType: SwitchType.scheckbox,
text: translate('Always connect via relay'),
@ -555,7 +566,9 @@ abstract class BasePeerCard extends StatelessWidget {
},
setter: (bool v) async {
await bind.mainSetPeerOption(
id: id, key: option, value: bool2option(option, v));
id: id,
key: kOptionForceAlwaysRelay,
value: bool2option(kOptionForceAlwaysRelay, v));
},
padding: menuPadding,
dismissOnClicked: true,
@ -813,7 +826,7 @@ class RecentPeerCard extends BasePeerCard {
Future<List<MenuEntryBase<String>>> _buildMenuItems(
BuildContext context) async {
final List<MenuEntryBase<String>> menuItems = [
..._connectActions(context, peer),
_connectAction(context, peer),
_transferFileAction(context, peer.id),
];
@ -822,6 +835,7 @@ class RecentPeerCard extends BasePeerCard {
if (isDesktop && peer.platform != 'Android') {
menuItems.add(_tcpTunnelingAction(context, peer.id));
}
// menuItems.add(await _openNewConnInOptAction(peer.id));
menuItems.add(await _forceAlwaysRelayAction(peer.id));
if (peer.platform == 'Windows') {
menuItems.add(_rdpAction(context, peer.id));
@ -869,12 +883,13 @@ class FavoritePeerCard extends BasePeerCard {
Future<List<MenuEntryBase<String>>> _buildMenuItems(
BuildContext context) async {
final List<MenuEntryBase<String>> menuItems = [
..._connectActions(context, peer),
_connectAction(context, peer),
_transferFileAction(context, peer.id),
];
if (isDesktop && peer.platform != 'Android') {
menuItems.add(_tcpTunnelingAction(context, peer.id));
}
// menuItems.add(await _openNewConnInOptAction(peer.id));
menuItems.add(await _forceAlwaysRelayAction(peer.id));
if (peer.platform == 'Windows') {
menuItems.add(_rdpAction(context, peer.id));
@ -919,7 +934,7 @@ class DiscoveredPeerCard extends BasePeerCard {
Future<List<MenuEntryBase<String>>> _buildMenuItems(
BuildContext context) async {
final List<MenuEntryBase<String>> menuItems = [
..._connectActions(context, peer),
_connectAction(context, peer),
_transferFileAction(context, peer.id),
];
@ -928,6 +943,7 @@ class DiscoveredPeerCard extends BasePeerCard {
if (isDesktop && peer.platform != 'Android') {
menuItems.add(_tcpTunnelingAction(context, peer.id));
}
// menuItems.add(await _openNewConnInOptAction(peer.id));
menuItems.add(await _forceAlwaysRelayAction(peer.id));
if (peer.platform == 'Windows') {
menuItems.add(_rdpAction(context, peer.id));
@ -971,12 +987,13 @@ class AddressBookPeerCard extends BasePeerCard {
Future<List<MenuEntryBase<String>>> _buildMenuItems(
BuildContext context) async {
final List<MenuEntryBase<String>> menuItems = [
..._connectActions(context, peer),
_connectAction(context, peer),
_transferFileAction(context, peer.id),
];
if (isDesktop && peer.platform != 'Android') {
menuItems.add(_tcpTunnelingAction(context, peer.id));
}
// menuItems.add(await _openNewConnInOptAction(peer.id));
menuItems.add(await _forceAlwaysRelayAction(peer.id));
if (peer.platform == 'Windows') {
menuItems.add(_rdpAction(context, peer.id));
@ -1033,12 +1050,13 @@ class MyGroupPeerCard extends BasePeerCard {
Future<List<MenuEntryBase<String>>> _buildMenuItems(
BuildContext context) async {
final List<MenuEntryBase<String>> menuItems = [
..._connectActions(context, peer),
_connectAction(context, peer),
_transferFileAction(context, peer.id),
];
if (isDesktop && peer.platform != 'Android') {
menuItems.add(_tcpTunnelingAction(context, peer.id));
}
// menuItems.add(await _openNewConnInOptAction(peer.id));
menuItems.add(await _forceAlwaysRelayAction(peer.id));
if (peer.platform == 'Windows') {
menuItems.add(_rdpAction(context, peer.id));

View File

@ -22,8 +22,6 @@ const String kAppTypeDesktopRemote = "remote";
const String kAppTypeDesktopFileTransfer = "file transfer";
const String kAppTypeDesktopPortForward = "port forward";
const bool kCloseMultiWindowByHide = true;
const String kWindowMainWindowOnTop = "main_window_on_top";
const String kWindowGetWindowInfo = "get_window_info";
const String kWindowDisableGrabKeyboard = "disable_grab_keyboard";
@ -42,7 +40,10 @@ const String kWindowEventGetSessionIdList = "get_session_id_list";
const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window";
const String kWindowEventCloseForSeparateWindow = "close_for_separate_window";
const String kOptionSeparateRemoteWindow = "allow-separate-remote-window";
const String kOptionOpenNewConnInTabs = "enable-open-new-connections-in-tabs";
const String kOptionOpenInTabs = "allow-open-in-tabs";
const String kOptionOpenInWindows = "allow-open-in-windows";
const String kOptionForceAlwaysRelay = "force-always-relay";
const String kUniLinksPrefix = "rustdesk://";
const String kUrlActionClose = "close";

View File

@ -554,13 +554,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
} else if (call.method == kWindowEventShow) {
await rustDeskWinManager.registerActiveWindow(call.arguments["id"]);
} else if (call.method == kWindowEventHide) {
final wId = call.arguments['id'];
final isSeparateWindowEnabled =
mainGetLocalBoolOptionSync(kOptionSeparateRemoteWindow);
if (isSeparateWindowEnabled && !kCloseMultiWindowByHide) {
await rustDeskWinManager.destroyWindow(wId);
}
await rustDeskWinManager.unregisterActiveWindow(wId);
await rustDeskWinManager.unregisterActiveWindow(call.arguments['id']);
} else if (call.method == kWindowConnect) {
await connectMainDesktop(
call.arguments['id'],
@ -568,7 +562,6 @@ class _DesktopHomePageState extends State<DesktopHomePage>
isTcpTunneling: call.arguments['isTcpTunneling'],
isRDP: call.arguments['isRDP'],
forceRelay: call.arguments['forceRelay'],
forceSeparateWindow: call.arguments['forceSeparateWindow'],
);
} else if (call.method == kWindowEventMoveTabToNewWindow) {
final args = call.arguments.split(',');

View File

@ -319,8 +319,8 @@ class _GeneralState extends State<_General> {
_OptionCheckBox(context, 'Adaptive bitrate', 'enable-abr'),
_OptionCheckBox(
context,
'Separate remote windows',
kOptionSeparateRemoteWindow,
'Open new connections in tabs',
kOptionOpenNewConnInTabs,
isServer: false,
),
];

View File

@ -116,7 +116,7 @@ class _RemotePageState extends State<RemotePage>
Wakelock.enable();
}
// Register texture.
if (mainGetLocalBoolOptionSync(kOptionSeparateRemoteWindow)) {
if (mainGetLocalBoolOptionSync(kOptionOpenNewConnInTabs)) {
_renderTexture = renderTexture;
} else {
_renderTexture = RenderTexture();

View File

@ -81,19 +81,24 @@ class RustDeskMultiWindowManager {
}
_newSession(
bool separateWindow,
bool openInTabs,
WindowType type,
String methodName,
String remoteId,
List<int> windows,
String msg,
) async {
if (separateWindow) {
if (kCloseMultiWindowByHide && _inactiveWindows.isNotEmpty) {
if (openInTabs) {
if (windows.isEmpty) {
await newSessionWindow(type, remoteId, msg, windows);
} else {
call(type, methodName, msg);
}
} else {
if (_inactiveWindows.isNotEmpty) {
for (final windowId in windows) {
if (_inactiveWindows.contains(windowId)) {
await DesktopMultiWindow.invokeMethod(
windowId, methodName, msg);
await DesktopMultiWindow.invokeMethod(windowId, methodName, msg);
WindowController.fromWindowId(windowId).show();
registerActiveWindow(windowId);
return;
@ -101,12 +106,6 @@ class RustDeskMultiWindowManager {
}
}
await newSessionWindow(type, remoteId, msg, windows);
} else {
if (windows.isEmpty) {
await newSessionWindow(type, remoteId, msg, windows);
} else {
call(type, methodName, msg);
}
}
}
@ -119,7 +118,6 @@ class RustDeskMultiWindowManager {
bool? forceRelay,
String? switchUuid,
bool? isRDP,
bool forceSeparateWindow = false,
}) async {
var params = {
"type": type.index,
@ -136,11 +134,10 @@ class RustDeskMultiWindowManager {
final msg = jsonEncode(params);
// separate window for file transfer is not supported
bool separateWindow = forceSeparateWindow ||
(type != WindowType.FileTransfer &&
mainGetLocalBoolOptionSync(kOptionSeparateRemoteWindow));
bool openInTabs = type != WindowType.RemoteDesktop ||
mainGetLocalBoolOptionSync(kOptionOpenNewConnInTabs);
if (windows.length > 1 || separateWindow) {
if (windows.length > 1 || !openInTabs) {
for (final windowId in windows) {
if (await DesktopMultiWindow.invokeMethod(
windowId, kWindowEventActiveSession, remoteId)) {
@ -149,7 +146,7 @@ class RustDeskMultiWindowManager {
}
}
await _newSession(separateWindow, type, methodName, remoteId, windows, msg);
await _newSession(openInTabs, type, methodName, remoteId, windows, msg);
}
Future<dynamic> newRemoteDesktop(
@ -157,7 +154,6 @@ class RustDeskMultiWindowManager {
String? password,
String? switchUuid,
bool? forceRelay,
bool forceSeparateWindow = false,
}) async {
return await newSession(
WindowType.RemoteDesktop,
@ -167,7 +163,6 @@ class RustDeskMultiWindowManager {
password: password,
forceRelay: forceRelay,
switchUuid: switchUuid,
forceSeparateWindow: forceSeparateWindow,
);
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "管理的设备数已达到最大值"),
("Sync with recent sessions", "同步最近会话"),
("Sort tags", "对标签进行排序"),
("Separate remote windows", "使用独立远程窗口"),
("separate window", "独立窗口"),
("Open new connections in tabs", "在选项卡中打开新连接"),
("Move tab to new window", "将标签页移至新窗口"),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Sie haben die maximale Anzahl der verwalteten Geräte erreicht."),
("Sync with recent sessions", "Synchronisierung mit den letzten Sitzungen"),
("Sort tags", "Tags sortieren"),
("Separate remote windows", "Separate entfernte Fenster"),
("separate window", "Separates Fenster"),
("Open new connections in tabs", ""),
("Move tab to new window", "Tab in neues Fenster verschieben"),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -12,6 +12,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("not_close_tcp_tip", "Don't close this window while you are using the tunnel"),
("setup_server_tip", "For faster connection, please set up your own server"),
("Auto Login", "Auto Login (Only valid if you set \"Lock after session end\")"),
("Always connect via relay", "Always Connect via Relay"),
("whitelist_tip", "Only whitelisted IP can access me"),
("whitelist_sep", "Separated by comma, semicolon, spaces or new line"),
("Wrong credentials", "Wrong username or password"),

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Has alcanzado el máximo número de dispositivos administrados."),
("Sync with recent sessions", "Sincronizar con sesiones recientes"),
("Sort tags", "Ordenar etiquetas"),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Hai raggiunto il numero massimo di dispositivi gestibili."),
("Sync with recent sessions", "Sincronizza con le sessioni recenti"),
("Sort tags", "Ordina etichette"),
("Separate remote windows", "Separa finestre remote"),
("separate window", "Separa finestra"),
("Open new connections in tabs", ""),
("Move tab to new window", "Sposta scheda nella finestra successiva"),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Het maximum aantal gecontroleerde apparaten is bereikt."),
("Sync with recent sessions", "Recente sessies synchroniseren"),
("Sort tags", "Labels sorteren"),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Przekroczona maks. liczba urządzeń"),
("Sync with recent sessions", "Synchronizacja z ostatnimi sesjami"),
("Sort tags", "Znaczniki sortowania"),
("Separate remote windows", "Oddzielne zdalne okna"),
("separate window", "oddzielne okno"),
("Open new connections in tabs", ""),
("Move tab to new window", "Przenieś zakładkę do nowego okna"),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Достигнуто максимальне количество управляемых устройств."),
("Sync with recent sessions", "Синхронизация последних сессий"),
("Sort tags", "Сортировка меток"),
("Separate remote windows", "Отдельные удалённые окна"),
("separate window", "отдельное окно"),
("Open new connections in tabs", ""),
("Move tab to new window", "Переместить вкладку в отдельное окно"),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}

View File

@ -524,8 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote windows", ""),
("separate window", ""),
("Open new connections in tabs", ""),
("Move tab to new window", ""),
].iter().cloned().collect();
}