refact, peer card menu, open in tabs or windows

Signed-off-by: dignow <linlong1265@gmail.com>
This commit is contained in:
dignow 2023-08-08 12:12:35 +08:00
parent 6b375cb0a3
commit ac88f55f25
41 changed files with 187 additions and 100 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 in windows', 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,16 @@ class RustDeskMultiWindowManager {
final msg = jsonEncode(params);
// separate window for file transfer is not supported
bool separateWindow = forceSeparateWindow ||
(type != WindowType.FileTransfer &&
mainGetLocalBoolOptionSync(kOptionSeparateRemoteWindow));
bool openInTabs = false;
if (type == WindowType.RemoteDesktop) {
if (mainGetLocalBoolOptionSync(kOptionOpenNewConnInTabs)) {
openInTabs = !mainGetPeerBoolOptionSync(remoteId, kOptionOpenInWindows);
} else {
openInTabs = mainGetPeerBoolOptionSync(remoteId, kOptionOpenInTabs);
}
}
if (windows.length > 1 || separateWindow) {
if (windows.length > 1 || !openInTabs) {
for (final windowId in windows) {
if (await DesktopMultiWindow.invokeMethod(
windowId, kWindowEventActiveSession, remoteId)) {
@ -149,7 +152,7 @@ class RustDeskMultiWindowManager {
}
}
await _newSession(separateWindow, type, methodName, remoteId, windows, msg);
await _newSession(openInTabs, type, methodName, remoteId, windows, msg);
}
Future<dynamic> newRemoteDesktop(
@ -157,7 +160,6 @@ class RustDeskMultiWindowManager {
String? password,
String? switchUuid,
bool? forceRelay,
bool forceSeparateWindow = false,
}) async {
return await newSession(
WindowType.RemoteDesktop,
@ -167,7 +169,6 @@ class RustDeskMultiWindowManager {
password: password,
forceRelay: forceRelay,
switchUuid: switchUuid,
forceSeparateWindow: forceSeparateWindow,
);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -524,7 +524,9 @@ 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"),
("Open new connections in tabs", ""),
("Open in tabs", ""),
("Open in windows", ""),
("separate window", "Separates Fenster"),
("Move tab to new window", "Tab in neues Fenster verschieben"),
].iter().cloned().collect();

View File

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

View File

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

View File

@ -524,7 +524,9 @@ 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", ""),
("Open new connections in tabs", ""),
("Open in tabs", ""),
("Open in windows", ""),
("separate window", ""),
("Move tab to new window", ""),
].iter().cloned().collect();

View File

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

View File

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

View File

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

View File

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

View File

@ -524,7 +524,9 @@ 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"),
("Open new connections in tabs", ""),
("Open in tabs", ""),
("Open in windows", ""),
("separate window", "Separa finestra"),
("Move tab to new window", "Sposta scheda nella finestra successiva"),
].iter().cloned().collect();

View File

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

View File

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

View File

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

View File

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

View File

@ -524,7 +524,9 @@ 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", ""),
("Open new connections in tabs", ""),
("Open in tabs", ""),
("Open in windows", ""),
("separate window", ""),
("Move tab to new window", ""),
].iter().cloned().collect();

View File

@ -524,7 +524,9 @@ 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"),
("Open new connections in tabs", ""),
("Open in tabs", ""),
("Open in windows", ""),
("separate window", "oddzielne okno"),
("Move tab to new window", "Przenieś zakładkę do nowego okna"),
].iter().cloned().collect();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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