mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-27 10:40:08 +00:00
Merge branch '2dust:master' into accessibility
This commit is contained in:
commit
ff7fc64575
18 changed files with 258 additions and 194 deletions
|
|
@ -18,8 +18,8 @@
|
||||||
<PackageVersion Include="ReactiveUI" Version="20.2.45" />
|
<PackageVersion Include="ReactiveUI" Version="20.2.45" />
|
||||||
<PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" />
|
<PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||||
<PackageVersion Include="ReactiveUI.WPF" Version="20.2.45" />
|
<PackageVersion Include="ReactiveUI.WPF" Version="20.2.45" />
|
||||||
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.6" />
|
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.7" />
|
||||||
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.6" />
|
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.7" />
|
||||||
<PackageVersion Include="Splat.NLog" Version="15.3.1" />
|
<PackageVersion Include="Splat.NLog" Version="15.3.1" />
|
||||||
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
|
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
<PackageVersion Include="TaskScheduler" Version="2.12.1" />
|
<PackageVersion Include="TaskScheduler" Version="2.12.1" />
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,6 @@ public sealed class AppHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAdministrator
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
_isAdministrator ??= Utils.IsAdministrator();
|
|
||||||
return _isAdministrator.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string LinuxSudoPwd { get; set; }
|
public string LinuxSudoPwd { get; set; }
|
||||||
|
|
||||||
#endregion Property
|
#endregion Property
|
||||||
|
|
|
||||||
144
v2rayN/ServiceLib/Handler/CoreAdminHandler.cs
Normal file
144
v2rayN/ServiceLib/Handler/CoreAdminHandler.cs
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using CliWrap;
|
||||||
|
|
||||||
|
namespace ServiceLib.Handler;
|
||||||
|
|
||||||
|
public class CoreAdminHandler
|
||||||
|
{
|
||||||
|
private static readonly Lazy<CoreAdminHandler> _instance = new(() => new());
|
||||||
|
public static CoreAdminHandler Instance => _instance.Value;
|
||||||
|
private Config _config;
|
||||||
|
private Action<bool, string>? _updateFunc;
|
||||||
|
private const string _tag = "CoreAdminHandler";
|
||||||
|
private int _linuxSudoPid = -1;
|
||||||
|
|
||||||
|
public async Task Init(Config config, Action<bool, string> updateFunc)
|
||||||
|
{
|
||||||
|
if (_config != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_config = config;
|
||||||
|
_updateFunc = updateFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateFunc(bool notify, string msg)
|
||||||
|
{
|
||||||
|
_updateFunc?.Invoke(notify, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Process?> RunProcessAsLinuxSudo(string fileName, CoreInfo coreInfo, string configPath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
|
||||||
|
var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
|
||||||
|
|
||||||
|
Process proc = new()
|
||||||
|
{
|
||||||
|
StartInfo = new()
|
||||||
|
{
|
||||||
|
FileName = shFilePath,
|
||||||
|
Arguments = "",
|
||||||
|
WorkingDirectory = Utils.GetBinConfigPath(),
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardInput = true,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
StandardInputEncoding = Encoding.UTF8,
|
||||||
|
StandardOutputEncoding = Encoding.UTF8,
|
||||||
|
StandardErrorEncoding = Encoding.UTF8,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
proc.OutputDataReceived += (sender, e) =>
|
||||||
|
{
|
||||||
|
if (e.Data.IsNotEmpty())
|
||||||
|
{
|
||||||
|
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
proc.ErrorDataReceived += (sender, e) =>
|
||||||
|
{
|
||||||
|
if (e.Data.IsNotEmpty())
|
||||||
|
{
|
||||||
|
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
proc.Start();
|
||||||
|
proc.BeginOutputReadLine();
|
||||||
|
proc.BeginErrorReadLine();
|
||||||
|
|
||||||
|
await Task.Delay(10);
|
||||||
|
await proc.StandardInput.WriteLineAsync();
|
||||||
|
await Task.Delay(10);
|
||||||
|
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
|
||||||
|
|
||||||
|
await Task.Delay(100);
|
||||||
|
if (proc is null or { HasExited: true })
|
||||||
|
{
|
||||||
|
throw new Exception(ResUI.FailedToRunCore);
|
||||||
|
}
|
||||||
|
|
||||||
|
_linuxSudoPid = proc.Id;
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
UpdateFunc(false, ex.Message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task KillProcessAsLinuxSudo()
|
||||||
|
{
|
||||||
|
if (_linuxSudoPid < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cmdLine = $"pkill -P {_linuxSudoPid} ; kill {_linuxSudoPid}";
|
||||||
|
var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh");
|
||||||
|
|
||||||
|
var result = await Cli.Wrap(shFilePath)
|
||||||
|
.WithStandardInputPipe(PipeSource.FromString(AppHandler.Instance.LinuxSudoPwd))
|
||||||
|
.ExecuteAsync();
|
||||||
|
|
||||||
|
_linuxSudoPid = -1;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, ex);
|
||||||
|
UpdateFunc(false, ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> CreateLinuxShellFile(string cmdLine, string fileName)
|
||||||
|
{
|
||||||
|
var shFilePath = Utils.GetBinConfigPath(fileName);
|
||||||
|
File.Delete(shFilePath);
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine("#!/bin/sh");
|
||||||
|
if (Utils.IsAdministrator())
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{cmdLine}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.AppendLine($"sudo -S {cmdLine}");
|
||||||
|
}
|
||||||
|
|
||||||
|
await File.WriteAllTextAsync(shFilePath, sb.ToString());
|
||||||
|
await Utils.SetLinuxChmod(shFilePath);
|
||||||
|
|
||||||
|
return shFilePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ public class CoreHandler
|
||||||
private Config _config;
|
private Config _config;
|
||||||
private Process? _process;
|
private Process? _process;
|
||||||
private Process? _processPre;
|
private Process? _processPre;
|
||||||
private int _linuxSudoPid = -1;
|
private bool _linuxSudo = false;
|
||||||
private Action<bool, string>? _updateFunc;
|
private Action<bool, string>? _updateFunc;
|
||||||
private const string _tag = "CoreHandler";
|
private const string _tag = "CoreHandler";
|
||||||
|
|
||||||
|
|
@ -155,23 +155,23 @@ public class CoreHandler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (_linuxSudo)
|
||||||
|
{
|
||||||
|
await CoreAdminHandler.Instance.KillProcessAsLinuxSudo();
|
||||||
|
_linuxSudo = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_process != null)
|
if (_process != null)
|
||||||
{
|
{
|
||||||
await ProcUtils.ProcessKill(_process, true);
|
await ProcUtils.ProcessKill(_process, Utils.IsWindows());
|
||||||
_process = null;
|
_process = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_processPre != null)
|
if (_processPre != null)
|
||||||
{
|
{
|
||||||
await ProcUtils.ProcessKill(_processPre, true);
|
await ProcUtils.ProcessKill(_processPre, Utils.IsWindows());
|
||||||
_processPre = null;
|
_processPre = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_linuxSudoPid > 0)
|
|
||||||
{
|
|
||||||
await KillProcessAsLinuxSudo();
|
|
||||||
}
|
|
||||||
_linuxSudoPid = -1;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -225,13 +225,6 @@ public class CoreHandler
|
||||||
_updateFunc?.Invoke(notify, msg);
|
_updateFunc?.Invoke(notify, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsNeedSudo(ECoreType eCoreType)
|
|
||||||
{
|
|
||||||
return _config.TunModeItem.EnableTun
|
|
||||||
&& eCoreType == ECoreType.sing_box
|
|
||||||
&& Utils.IsNonWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private
|
#endregion Private
|
||||||
|
|
||||||
#region Process
|
#region Process
|
||||||
|
|
@ -245,6 +238,16 @@ public class CoreHandler
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mayNeedSudo
|
||||||
|
&& _config.TunModeItem.EnableTun
|
||||||
|
&& coreInfo.CoreType == ECoreType.sing_box
|
||||||
|
&& Utils.IsNonWindows())
|
||||||
|
{
|
||||||
|
_linuxSudo = true;
|
||||||
|
await CoreAdminHandler.Instance.Init(_config, _updateFunc);
|
||||||
|
return await CoreAdminHandler.Instance.RunProcessAsLinuxSudo(fileName, coreInfo, configPath);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Process proc = new()
|
Process proc = new()
|
||||||
|
|
@ -263,38 +266,25 @@ public class CoreHandler
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var isNeedSudo = mayNeedSudo && IsNeedSudo(coreInfo.CoreType);
|
|
||||||
if (isNeedSudo)
|
|
||||||
{
|
|
||||||
await RunProcessAsLinuxSudo(proc, fileName, coreInfo, configPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (displayLog)
|
if (displayLog)
|
||||||
{
|
{
|
||||||
proc.OutputDataReceived += (sender, e) =>
|
proc.OutputDataReceived += (sender, e) =>
|
||||||
{
|
{
|
||||||
if (e.Data.IsNullOrEmpty())
|
if (e.Data.IsNotEmpty())
|
||||||
return;
|
{
|
||||||
UpdateFunc(false, e.Data + Environment.NewLine);
|
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
proc.ErrorDataReceived += (sender, e) =>
|
proc.ErrorDataReceived += (sender, e) =>
|
||||||
{
|
{
|
||||||
if (e.Data.IsNullOrEmpty())
|
if (e.Data.IsNotEmpty())
|
||||||
return;
|
{
|
||||||
UpdateFunc(false, e.Data + Environment.NewLine);
|
UpdateFunc(false, e.Data + Environment.NewLine);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
proc.Start();
|
proc.Start();
|
||||||
|
|
||||||
if (isNeedSudo && AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
|
|
||||||
{
|
|
||||||
await proc.StandardInput.WriteLineAsync();
|
|
||||||
await Task.Delay(10);
|
|
||||||
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
|
|
||||||
}
|
|
||||||
if (isNeedSudo)
|
|
||||||
_linuxSudoPid = proc.Id;
|
|
||||||
|
|
||||||
if (displayLog)
|
if (displayLog)
|
||||||
{
|
{
|
||||||
proc.BeginOutputReadLine();
|
proc.BeginOutputReadLine();
|
||||||
|
|
@ -318,82 +308,4 @@ public class CoreHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Process
|
#endregion Process
|
||||||
|
|
||||||
#region Linux
|
|
||||||
|
|
||||||
private async Task RunProcessAsLinuxSudo(Process proc, string fileName, CoreInfo coreInfo, string configPath)
|
|
||||||
{
|
|
||||||
var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetBinConfigPath(configPath).AppendQuotes())}";
|
|
||||||
|
|
||||||
var shFilePath = await CreateLinuxShellFile(cmdLine, "run_as_sudo.sh");
|
|
||||||
proc.StartInfo.FileName = shFilePath;
|
|
||||||
proc.StartInfo.Arguments = "";
|
|
||||||
proc.StartInfo.WorkingDirectory = "";
|
|
||||||
if (AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
|
|
||||||
{
|
|
||||||
proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
|
|
||||||
proc.StartInfo.RedirectStandardInput = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task KillProcessAsLinuxSudo()
|
|
||||||
{
|
|
||||||
var cmdLine = $"pkill -P {_linuxSudoPid} ; kill {_linuxSudoPid}";
|
|
||||||
var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh");
|
|
||||||
Process proc = new()
|
|
||||||
{
|
|
||||||
StartInfo = new()
|
|
||||||
{
|
|
||||||
FileName = shFilePath,
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true,
|
|
||||||
StandardInputEncoding = Encoding.UTF8,
|
|
||||||
RedirectStandardInput = true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
proc.Start();
|
|
||||||
|
|
||||||
if (AppHandler.Instance.LinuxSudoPwd.IsNotEmpty())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await proc.StandardInput.WriteLineAsync();
|
|
||||||
await Task.Delay(10);
|
|
||||||
await proc.StandardInput.WriteLineAsync(AppHandler.Instance.LinuxSudoPwd);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10));
|
|
||||||
await proc.WaitForExitAsync(timeout.Token);
|
|
||||||
await Task.Delay(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<string> CreateLinuxShellFile(string cmdLine, string fileName)
|
|
||||||
{
|
|
||||||
//Shell scripts
|
|
||||||
var shFilePath = Utils.GetBinConfigPath(AppHandler.Instance.IsAdministrator ? "root_" + fileName : fileName);
|
|
||||||
File.Delete(shFilePath);
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("#!/bin/sh");
|
|
||||||
if (AppHandler.Instance.IsAdministrator)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{cmdLine}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.AppendLine($"sudo -S {cmdLine}");
|
|
||||||
}
|
|
||||||
|
|
||||||
await File.WriteAllTextAsync(shFilePath, sb.ToString());
|
|
||||||
await Utils.SetLinuxChmod(shFilePath);
|
|
||||||
Logging.SaveLog(shFilePath);
|
|
||||||
|
|
||||||
return shFilePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Linux
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1339,7 +1339,7 @@
|
||||||
<value>رمز عبور sudo سیستم</value>
|
<value>رمز عبور sudo سیستم</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
|
||||||
<value>The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.</value>
|
<value>رمز عبوری که وارد کرده اید تایید نمی شود، بنابراین مطمئن شوید که آن را به درستی وارد کرده اید. اگر برنامه به دلیل ورودی نادرست به درستی کار نمی کند، لطفاً برنامه را مجدداً راه اندازی کنید. رمز عبور ذخیره نمی شود و پس از هر بار راه اندازی مجدد باید آن را دوباره وارد کنید.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
<data name="TbSettingsLinuxSudoPasswordIsEmpty" xml:space="preserve">
|
||||||
<value>لطفاً ابتدا رمز عبور sudo را در تنظیمات حالت Tun تنظیم کنید</value>
|
<value>لطفاً ابتدا رمز عبور sudo را در تنظیمات حالت Tun تنظیم کنید</value>
|
||||||
|
|
@ -1416,4 +1416,4 @@
|
||||||
<data name="menuExportConfig" xml:space="preserve">
|
<data name="menuExportConfig" xml:space="preserve">
|
||||||
<value>صادر کردن سرور</value>
|
<value>صادر کردن سرور</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
||||||
|
|
@ -454,7 +454,7 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
if (Utils.IsWindows())
|
if (Utils.IsWindows())
|
||||||
{
|
{
|
||||||
return AppHandler.Instance.IsAdministrator;
|
return Utils.IsAdministrator();
|
||||||
}
|
}
|
||||||
else if (Utils.IsLinux())
|
else if (Utils.IsLinux())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ public partial class MainWindow : ReactiveWindow<MainWindowViewModel>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (AppHandler.Instance.IsAdministrator)
|
if (Utils.IsAdministrator())
|
||||||
{
|
{
|
||||||
this.Title = $"{Utils.GetVersion()} - {ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp}";
|
this.Title = $"{Utils.GetVersion()} - {ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp}";
|
||||||
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp);
|
NoticeHandler.Instance.SendMessageAndEnqueue(ResUI.TbSettingsLinuxSudoPasswordNotSudoRunApp);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ using DialogHostAvalonia;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
using Splat;
|
||||||
using v2rayN.Desktop.Common;
|
using v2rayN.Desktop.Common;
|
||||||
using static QRCoder.PayloadGenerator;
|
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Views;
|
namespace v2rayN.Desktop.Views;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
<Application
|
<Application
|
||||||
x:Class="v2rayN.App"
|
x:Class="v2rayN.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
ShutdownMode="OnExplicitShutdown"
|
ShutdownMode="OnExplicitShutdown"
|
||||||
StartupUri="Views/MainWindow.xaml">
|
StartupUri="Views/MainWindow.xaml">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.MainWindow"
|
x:Class="v2rayN.Views.MainWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
|
||||||
xmlns:view="clr-namespace:v2rayN.Views"
|
xmlns:view="clr-namespace:v2rayN.Views"
|
||||||
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="v2rayN"
|
Title="v2rayN"
|
||||||
Width="900"
|
Width="900"
|
||||||
Height="700"
|
Height="700"
|
||||||
|
|
@ -43,8 +43,7 @@
|
||||||
Style="{StaticResource MaterialDesignToolBar}"
|
Style="{StaticResource MaterialDesignToolBar}"
|
||||||
KeyboardNavigation.TabNavigation="Continue">
|
KeyboardNavigation.TabNavigation="Continue">
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem Padding="8,0"
|
<MenuItem Padding="8,0" AutomationProperties.Name="{x:Static resx:ResUI.menuServers}">
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}">
|
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -112,8 +111,7 @@
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem Padding="8,0"
|
<MenuItem Padding="8,0" AutomationProperties.Name="{x:Static resx:ResUI.menuSubscription}">
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuSubscription}">
|
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -148,8 +146,7 @@
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem Padding="8,0"
|
<MenuItem Padding="8,0" AutomationProperties.Name="{x:Static resx:ResUI.menuSetting}">
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuSetting}">
|
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -215,8 +212,10 @@
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem x:Name="menuReload" Padding="8,0"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuReload}">
|
x:Name="menuReload"
|
||||||
|
Padding="8,0"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuReload}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -230,8 +229,10 @@
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem Name="menuCheckUpdate" Padding="8,0"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuCheckUpdate}">
|
Name="menuCheckUpdate"
|
||||||
|
Padding="8,0"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuCheckUpdate}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -245,8 +246,10 @@
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem x:Name="menuHelp" Padding="8,0"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuHelp}">
|
x:Name="menuHelp"
|
||||||
|
Padding="8,0"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuHelp}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -260,8 +263,10 @@
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem x:Name="menuPromotion" Padding="8,0"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuPromotion}">
|
x:Name="menuPromotion"
|
||||||
|
Padding="8,0"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuPromotion}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -275,8 +280,10 @@
|
||||||
</Menu>
|
</Menu>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
<Menu Margin="0,1" Style="{StaticResource ToolbarMenu}">
|
||||||
<MenuItem x:Name="menuClose" Padding="8,0"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuClose}">
|
x:Name="menuClose"
|
||||||
|
Padding="8,0"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuClose}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ public partial class MainWindow
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.Title = $"{Utils.GetVersion()} - {(AppHandler.Instance.IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||||
|
|
||||||
if (!_config.GuiItem.EnableHWA)
|
if (!_config.GuiItem.EnableHWA)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,9 @@
|
||||||
Width="30"
|
Width="30"
|
||||||
Height="30"
|
Height="30"
|
||||||
Margin="{StaticResource MarginLeftRight4}"
|
Margin="{StaticResource MarginLeftRight4}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuSubEdit}"
|
||||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||||
ToolTip="{x:Static resx:ResUI.menuSubEdit}"
|
ToolTip="{x:Static resx:ResUI.menuSubEdit}">
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuSubEdit}">
|
|
||||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Edit" />
|
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Edit" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -50,9 +50,9 @@
|
||||||
Width="30"
|
Width="30"
|
||||||
Height="30"
|
Height="30"
|
||||||
Margin="{StaticResource MarginLeftRight4}"
|
Margin="{StaticResource MarginLeftRight4}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuSubAdd}"
|
||||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||||
ToolTip="{x:Static resx:ResUI.menuSubAdd}"
|
ToolTip="{x:Static resx:ResUI.menuSubAdd}">
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuSubAdd}">
|
|
||||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Plus" />
|
<materialDesign:PackIcon VerticalAlignment="Center" Kind="Plus" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
@ -61,9 +61,9 @@
|
||||||
Width="30"
|
Width="30"
|
||||||
Height="30"
|
Height="30"
|
||||||
Margin="{StaticResource MarginLeftRight8}"
|
Margin="{StaticResource MarginLeftRight8}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}"
|
||||||
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}"
|
||||||
ToolTip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}"
|
ToolTip="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuProfileAutofitColumnWidth}">
|
|
||||||
<materialDesign:PackIcon VerticalAlignment="Center" Kind="ArrowSplitVertical" />
|
<materialDesign:PackIcon VerticalAlignment="Center" Kind="ArrowSplitVertical" />
|
||||||
</Button>
|
</Button>
|
||||||
<TextBox
|
<TextBox
|
||||||
|
|
@ -73,8 +73,8 @@
|
||||||
VerticalContentAlignment="Center"
|
VerticalContentAlignment="Center"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}"
|
||||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||||
Style="{StaticResource DefTextBox}"
|
AutomationProperties.Name="{x:Static resx:ResUI.MsgServerTitle}"
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.MsgServerTitle}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<DataGrid
|
<DataGrid
|
||||||
x:Name="lstProfiles"
|
x:Name="lstProfiles"
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.RoutingRuleDetailsWindow"
|
x:Class="v2rayN.Views.RoutingRuleDetailsWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"
|
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.RoutingRuleSettingWindow"
|
x:Class="v2rayN.Views.RoutingRuleSettingWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"
|
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,8 @@
|
||||||
x:Name="togEnableTun"
|
x:Name="togEnableTun"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Center" AutomationProperties.Name="{x:Static resx:ResUI.TbEnableTunAs}" />
|
VerticalAlignment="Center"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.TbEnableTunAs}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
|
|
@ -74,9 +75,9 @@
|
||||||
Width="160"
|
Width="160"
|
||||||
Margin="{StaticResource MarginLeftRight8}"
|
Margin="{StaticResource MarginLeftRight8}"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSystemproxy}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSystemproxy}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemproxy}"
|
||||||
FontSize="{DynamicResource StdFontSize}"
|
FontSize="{DynamicResource StdFontSize}"
|
||||||
Style="{StaticResource MaterialDesignFloatingHintComboBox}"
|
Style="{StaticResource MaterialDesignFloatingHintComboBox}">
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemproxy}">
|
|
||||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
|
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyClear}" />
|
||||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
|
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxySet}" />
|
||||||
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
<ComboBoxItem Content="{x:Static resx:ResUI.menuSystemProxyNothing}" />
|
||||||
|
|
@ -88,10 +89,10 @@
|
||||||
Width="160"
|
Width="160"
|
||||||
Margin="{StaticResource MarginLeftRight8}"
|
Margin="{StaticResource MarginLeftRight8}"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
|
||||||
DisplayMemberPath="Remarks"
|
DisplayMemberPath="Remarks"
|
||||||
FontSize="{DynamicResource StdFontSize}"
|
FontSize="{DynamicResource StdFontSize}"
|
||||||
Style="{StaticResource MaterialDesignFloatingHintComboBox}"
|
Style="{StaticResource MaterialDesignFloatingHintComboBox}" />
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"/>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Margin="{StaticResource MarginLeftRight8}" VerticalAlignment="Center">
|
<StackPanel Margin="{StaticResource MarginLeftRight8}" VerticalAlignment="Center">
|
||||||
|
|
@ -109,8 +110,10 @@
|
||||||
ToolTipText="v2rayN">
|
ToolTipText="v2rayN">
|
||||||
<tb:TaskbarIcon.ContextMenu>
|
<tb:TaskbarIcon.ContextMenu>
|
||||||
<ContextMenu Style="{StaticResource DefContextMenu}">
|
<ContextMenu Style="{StaticResource DefContextMenu}">
|
||||||
<MenuItem x:Name="menuSystemProxyClear" Height="{StaticResource MenuItemHeight}"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxyClear}">
|
x:Name="menuSystemProxyClear"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxyClear}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -122,8 +125,10 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</MenuItem.Header>
|
</MenuItem.Header>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem x:Name="menuSystemProxySet" Height="{StaticResource MenuItemHeight}"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxySet}">
|
x:Name="menuSystemProxySet"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxySet}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -135,8 +140,10 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</MenuItem.Header>
|
</MenuItem.Header>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem x:Name="menuSystemProxyNothing" Height="{StaticResource MenuItemHeight}"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxyNothing}">
|
x:Name="menuSystemProxyNothing"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxyNothing}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -148,8 +155,10 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</MenuItem.Header>
|
</MenuItem.Header>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem x:Name="menuSystemProxyPac" Height="{StaticResource MenuItemHeight}"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxyPac}">
|
x:Name="menuSystemProxyPac"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuSystemProxyPac}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<materialDesign:PackIcon
|
<materialDesign:PackIcon
|
||||||
|
|
@ -162,18 +171,20 @@
|
||||||
</MenuItem.Header>
|
</MenuItem.Header>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Separator x:Name="sepRoutings" />
|
<Separator x:Name="sepRoutings" />
|
||||||
<MenuItem x:Name="menuRoutings" Height="Auto"
|
<MenuItem
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}">
|
x:Name="menuRoutings"
|
||||||
|
Height="Auto"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}">
|
||||||
<MenuItem.Header>
|
<MenuItem.Header>
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<ComboBox
|
<ComboBox
|
||||||
x:Name="cmbRoutings"
|
x:Name="cmbRoutings"
|
||||||
MaxWidth="300"
|
MaxWidth="300"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"
|
||||||
DisplayMemberPath="Remarks"
|
DisplayMemberPath="Remarks"
|
||||||
FontSize="{DynamicResource StdFontSize}"
|
FontSize="{DynamicResource StdFontSize}"
|
||||||
Style="{StaticResource MaterialDesignFilledComboBox}"
|
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuRouting}"/>
|
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</MenuItem.Header>
|
</MenuItem.Header>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
@ -184,10 +195,10 @@
|
||||||
x:Name="cmbServers"
|
x:Name="cmbServers"
|
||||||
MaxWidth="300"
|
MaxWidth="300"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuServers}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuServers}"
|
||||||
|
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}"
|
||||||
DisplayMemberPath="Text"
|
DisplayMemberPath="Text"
|
||||||
FontSize="{DynamicResource StdFontSize}"
|
FontSize="{DynamicResource StdFontSize}"
|
||||||
Style="{StaticResource MaterialDesignFilledComboBox}"
|
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||||
AutomationProperties.Name="{x:Static resx:ResUI.menuServers}"/>
|
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</MenuItem.Header>
|
</MenuItem.Header>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.SubEditWindow"
|
x:Class="v2rayN.Views.SubEditWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuSubSetting}"
|
Title="{x:Static resx:ResUI.menuSubSetting}"
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.SubSettingWindow"
|
x:Class="v2rayN.Views.SubSettingWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
Title="{x:Static resx:ResUI.menuSubSetting}"
|
Title="{x:Static resx:ResUI.menuSubSetting}"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<reactiveui:ReactiveUserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.ThemeSettingView"
|
x:Class="v2rayN.Views.ThemeSettingView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue