Add support for custom PAC and proxy script paths

Introduces options to specify custom PAC file and system proxy script paths for system proxy settings. Updates configuration models, view models, UI bindings, and logic for Linux/OSX proxy handling and PAC management to use these custom paths if provided. Also adds UI elements and localization for the new settings.
This commit is contained in:
2dust
2025-11-07 19:28:16 +08:00
parent 753e7b81b6
commit ddc8c9b1cd
18 changed files with 203 additions and 18 deletions
@@ -674,6 +674,29 @@
<TabItem Name="tabSystemproxy" Header="{x:Static resx:ResUI.TbSettingsSystemproxy}">
<DockPanel Margin="{StaticResource Margin8}">
<StackPanel
Name="panSystemProxyUnix"
DockPanel.Dock="Bottom"
Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsCustomSystemProxyScriptPath}" />
<TextBox
x:Name="txtCustomSystemProxyScriptPath"
Width="600"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
TextWrapping="Wrap"
Watermark="proxy_set.sh"/>
<Button
x:Name="btnBrowseCustomSystemProxyScriptPath"
Margin="{StaticResource Margin4}"
Content="{x:Static resx:ResUI.TbBrowse}" />
</StackPanel>
</StackPanel>
<StackPanel
Name="panSystemProxyAdvanced"
DockPanel.Dock="Bottom"
@@ -699,6 +722,25 @@
MinWidth="400"
Margin="{StaticResource Margin4}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsCustomSystemProxyPacPath}" />
<TextBox
x:Name="txtCustomSystemProxyPacPath"
Width="600"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
TextWrapping="Wrap"
Watermark="pac.txt"/>
<Button
x:Name="btnBrowseCustomSystemProxyPacPath"
Margin="{StaticResource Margin4}"
Content="{x:Static resx:ResUI.TbBrowse}" />
</StackPanel>
</StackPanel>
<TextBlock
@@ -1,4 +1,5 @@
using v2rayN.Desktop.Base;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views;
@@ -17,6 +18,9 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
btnBrowseCustomSystemProxyPacPath.Click += BtnBrowseCustomSystemProxyPacPath_Click;
btnBrowseCustomSystemProxyScriptPath.Click += BtnBrowseCustomSystemProxyScriptPath_Click;
clbdestOverride.ItemsSource = Global.destOverrideProtocols;
_config.Inbound.First().DestOverride?.ForEach(it =>
{
@@ -101,6 +105,8 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
this.Bind(ViewModel, vm => vm.notProxyLocalAddress, v => v.tognotProxyLocalAddress.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.systemProxyExceptions, v => v.txtsystemProxyExceptions.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CustomSystemProxyPacPath, v => v.txtCustomSystemProxyPacPath.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CustomSystemProxyScriptPath, v => v.txtCustomSystemProxyScriptPath.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunAutoRoute, v => v.togAutoRoute.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunStrictRoute, v => v.togStrictRoute.IsChecked).DisposeWith(disposables);
@@ -127,6 +133,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
labHide2TrayWhenClose.IsVisible = false;
togHide2TrayWhenClose.IsVisible = false;
labHide2TrayWhenCloseTip.IsVisible = false;
panSystemProxyUnix.IsVisible = false;
}
else if (Utils.IsLinux())
{
@@ -212,6 +219,28 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
}
}
private async void BtnBrowseCustomSystemProxyPacPath_Click(object? sender, RoutedEventArgs e)
{
var fileName = await UI.OpenFileDialog(this, null);
if (fileName.IsNullOrEmpty())
{
return;
}
txtCustomSystemProxyPacPath.Text = fileName;
}
private async void BtnBrowseCustomSystemProxyScriptPath_Click(object? sender, RoutedEventArgs e)
{
var fileName = await UI.OpenFileDialog(this, null);
if (fileName.IsNullOrEmpty())
{
return;
}
txtCustomSystemProxyScriptPath.Text = fileName;
}
private void Window_Loaded(object? sender, RoutedEventArgs e)
{
btnCancel.Focus();