mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-27 10:40:08 +00:00
Compare commits
No commits in common. "dbd3ca44c2dca8e11848b629376caa38cb708391" and "29e8df7d2ebebb239a9f473618c65968f83a0865" have entirely different histories.
dbd3ca44c2
...
29e8df7d2e
10 changed files with 149 additions and 153 deletions
7
.github/workflows/build-linux.yml
vendored
7
.github/workflows/build-linux.yml
vendored
|
|
@ -42,7 +42,7 @@ jobs:
|
||||||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 --self-contained=true -p:PublishTrimmed=true -o $OutputPathArm64
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 --self-contained=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4.6.1
|
uses: actions/upload-artifact@v4.6.0
|
||||||
with:
|
with:
|
||||||
name: v2rayN-linux
|
name: v2rayN-linux
|
||||||
path: |
|
path: |
|
||||||
|
|
@ -68,8 +68,9 @@ jobs:
|
||||||
- name: Package AppImage
|
- name: Package AppImage
|
||||||
if: github.event.inputs.release_tag != ''
|
if: github.event.inputs.release_tag != ''
|
||||||
run: |
|
run: |
|
||||||
chmod a+x package-appimage.sh
|
chmod 755 package-appimage.sh
|
||||||
./package-appimage.sh
|
./package-appimage.sh $OutputArch $OutputPath64 ${{ github.event.inputs.release_tag }}
|
||||||
|
./package-appimage.sh $OutputArchArm $OutputPathArm64 ${{ github.event.inputs.release_tag }}
|
||||||
|
|
||||||
- name: Upload AppImage to release
|
- name: Upload AppImage to release
|
||||||
uses: svenstaro/upload-release-action@v2
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
|
|
||||||
2
.github/workflows/build-osx.yml
vendored
2
.github/workflows/build-osx.yml
vendored
|
|
@ -42,7 +42,7 @@ jobs:
|
||||||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 --self-contained=true -p:PublishTrimmed=true -o $OutputPathArm64
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 --self-contained=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4.6.1
|
uses: actions/upload-artifact@v4.6.0
|
||||||
with:
|
with:
|
||||||
name: v2rayN-macos
|
name: v2rayN-macos
|
||||||
path: |
|
path: |
|
||||||
|
|
|
||||||
2
.github/workflows/build-windows-desktop.yml
vendored
2
.github/workflows/build-windows-desktop.yml
vendored
|
|
@ -42,7 +42,7 @@ jobs:
|
||||||
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 --self-contained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64
|
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 --self-contained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4.6.1
|
uses: actions/upload-artifact@v4.6.0
|
||||||
with:
|
with:
|
||||||
name: v2rayN-windows-desktop
|
name: v2rayN-windows-desktop
|
||||||
path: |
|
path: |
|
||||||
|
|
|
||||||
2
.github/workflows/build-windows.yml
vendored
2
.github/workflows/build-windows.yml
vendored
|
|
@ -46,7 +46,7 @@ jobs:
|
||||||
|
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4.6.1
|
uses: actions/upload-artifact@v4.6.0
|
||||||
with:
|
with:
|
||||||
name: v2rayN-windows
|
name: v2rayN-windows
|
||||||
path: |
|
path: |
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,71 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
sudo apt update -y
|
Arch="$1"
|
||||||
|
OutputPath="$2"
|
||||||
|
Version="$3"
|
||||||
|
|
||||||
|
FileName="v2rayN-${Arch}.zip"
|
||||||
|
wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/$FileName"
|
||||||
|
7z x $FileName -aoa
|
||||||
|
cp -rf v2rayN-${Arch}/* $OutputPath
|
||||||
|
|
||||||
|
PackagePath="v2rayN-Package-${Arch}"
|
||||||
|
mkdir -p "${PackagePath}/AppDir/opt"
|
||||||
|
cp -rf $OutputPath "${PackagePath}/AppDir/opt/v2rayN"
|
||||||
|
echo "When this file exists, app will not store configs under this folder" >"${PackagePath}/AppDir/opt/v2rayN/NotStoreConfigHere.txt"
|
||||||
|
|
||||||
|
if [ $Arch = "linux-64" ]; then
|
||||||
|
Arch2="x86_64"
|
||||||
|
Arch3="amd64"
|
||||||
|
else
|
||||||
|
Arch2="aarch64"
|
||||||
|
Arch3="arm64"
|
||||||
|
fi
|
||||||
|
echo $Arch2
|
||||||
|
|
||||||
|
# basic
|
||||||
|
cat >"${PackagePath}/AppDir/AppRun" <<-EOF
|
||||||
|
#!/bin/sh
|
||||||
|
HERE="\$(dirname "\$(readlink -f "\${0}")")"
|
||||||
|
export PATH="\${HERE}"/opt/v2rayN/:"\${PATH}"
|
||||||
|
export LD_LIBRARY_PATH="\${HERE}"/opt/v2rayN/:"\${LD_LIBRARY_PATH}"
|
||||||
|
exec "\${HERE}/opt/v2rayN/v2rayN" \$@
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat >"${PackagePath}/AppDir/v2rayN.desktop" <<-EOF
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=v2rayN
|
||||||
|
Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
|
||||||
|
Exec=v2rayN
|
||||||
|
Icon=v2rayN
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Network;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo cp "${PackagePath}/AppDir/opt/v2rayN/v2rayN.png" "${PackagePath}/AppDir/v2rayN.png"
|
||||||
|
sudo dpkg --add-architecture ${Arch3}
|
||||||
|
mkdir deb_folder
|
||||||
|
cd deb_folder
|
||||||
|
apt download libicu74:${Arch3}
|
||||||
|
apt download libfontconfig1:${Arch3} || true
|
||||||
|
apt download libfontconfig:${Arch3} || true
|
||||||
|
mkdir ../output_folder
|
||||||
|
for deb in *.deb; do
|
||||||
|
dpkg-deb -x "$deb" ../output_folder/
|
||||||
|
done
|
||||||
|
cd ..
|
||||||
|
find output_folder -type f -name "*.so*" -exec cp {} ${PackagePath}/AppDir/opt/v2rayN/ \;
|
||||||
|
find output_folder -type l -name "*.so*" -exec cp {} ${PackagePath}/AppDir/opt/v2rayN/ \;
|
||||||
|
rm -rf deb_folder output_folder
|
||||||
|
|
||||||
|
sudo chmod 0755 "${PackagePath}/AppDir/opt/v2rayN/v2rayN"
|
||||||
|
sudo chmod 0755 "${PackagePath}/AppDir/AppRun"
|
||||||
|
|
||||||
|
# desktop && PATH
|
||||||
|
|
||||||
|
wget "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||||
|
chmod a+x appimagetool-x86_64.AppImage
|
||||||
sudo apt install -y libfuse2
|
sudo apt install -y libfuse2
|
||||||
wget -O pkg2appimage https://github.com/AppImageCommunity/pkg2appimage/releases/download/continuous/pkg2appimage-1eceb30-x86_64.AppImage
|
sudo ./appimagetool-x86_64.AppImage "${PackagePath}/AppDir"
|
||||||
chmod a+x pkg2appimage
|
sudo mv "v2rayN-${Arch2}.AppImage" "v2rayN-${Arch}.AppImage"
|
||||||
export AppImageOutputArch=$OutputArch
|
|
||||||
export OutputPath=$OutputPath64
|
|
||||||
./pkg2appimage ./pkg2appimage.yml
|
|
||||||
mv out/*.AppImage v2rayN-${AppImageOutputArch}.AppImage
|
|
||||||
export AppImageOutputArch=$OutputArchArm
|
|
||||||
export OutputPath=$OutputPathArm64
|
|
||||||
./pkg2appimage ./pkg2appimage.yml
|
|
||||||
mv out/*.AppImage v2rayN-${AppImageOutputArch}.AppImage
|
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
app: v2rayN
|
|
||||||
binpatch: true
|
|
||||||
|
|
||||||
ingredients:
|
|
||||||
script:
|
|
||||||
- export FileName="v2rayN-${AppImageOutputArch}.zip"
|
|
||||||
- wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/${FileName}"
|
|
||||||
- 7z x $FileName -aoa
|
|
||||||
- cp -rf v2rayN-${AppImageOutputArch}/* $OutputPath
|
|
||||||
|
|
||||||
script:
|
|
||||||
- mkdir -p usr/bin usr/lib
|
|
||||||
- cp -rf $OutputPath usr/lib/v2rayN
|
|
||||||
- echo "When this file exists, app will not store configs under this folder" > usr/lib/v2rayN/NotStoreConfigHere.txt
|
|
||||||
- ln -sf usr/lib/v2rayN/v2rayN usr/bin/v2rayN
|
|
||||||
- chmod a+x usr/lib/v2rayN/v2rayN
|
|
||||||
- find usr -type f -exec sh -c 'file "{}" | grep -qi "executable" && chmod +x "{}"' \;
|
|
||||||
- install -Dm644 usr/lib/v2rayN/v2rayN.png v2rayN.png
|
|
||||||
- install -Dm644 usr/lib/v2rayN/v2rayN.png usr/share/pixmaps/v2rayN.png
|
|
||||||
- cat > v2rayN.desktop <<EOF
|
|
||||||
- [Desktop Entry]
|
|
||||||
- Name=v2rayN
|
|
||||||
- Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
|
|
||||||
- Exec=v2rayN
|
|
||||||
- Icon=v2rayN
|
|
||||||
- Terminal=false
|
|
||||||
- Type=Application
|
|
||||||
- Categories=Network;
|
|
||||||
- EOF
|
|
||||||
- install -Dm644 v2rayN.desktop usr/share/applications/v2rayN.desktop
|
|
||||||
- cat > AppRun <<\EOF
|
|
||||||
- #!/bin/sh
|
|
||||||
- HERE="$(dirname "$(readlink -f "${0}")")"
|
|
||||||
- cd ${HERE}/usr/lib/v2rayN
|
|
||||||
- exec ${HERE}/usr/lib/v2rayN/v2rayN $@
|
|
||||||
- EOF
|
|
||||||
- chmod a+x AppRun
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<DockPanel Margin="2">
|
<DockPanel Margin="2">
|
||||||
<WrapPanel
|
<WrapPanel
|
||||||
Margin="{StaticResource Margin4}"
|
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
DockPanel.Dock="Top"
|
DockPanel.Dock="Top"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
|
|
||||||
|
|
@ -37,8 +37,6 @@
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
x:Name="btnClear"
|
x:Name="btnClear"
|
||||||
Width="{StaticResource IconButtonWidth}"
|
|
||||||
Height="{StaticResource IconButtonHeight}"
|
|
||||||
Margin="{StaticResource MarginLr8}"
|
Margin="{StaticResource MarginLr8}"
|
||||||
Classes="Success"
|
Classes="Success"
|
||||||
Click="menuMsgViewClear_Click"
|
Click="menuMsgViewClear_Click"
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,15 @@ namespace v2rayN.Handler
|
||||||
{
|
{
|
||||||
private static readonly Lazy<HotkeyHandler> _instance = new(() => new());
|
private static readonly Lazy<HotkeyHandler> _instance = new(() => new());
|
||||||
public static HotkeyHandler Instance = _instance.Value;
|
public static HotkeyHandler Instance = _instance.Value;
|
||||||
|
|
||||||
private const int WmHotkey = 0x0312;
|
private const int WmHotkey = 0x0312;
|
||||||
private readonly Dictionary<int, List<EGlobalHotkey>> _hotkeyTriggerDic = new();
|
|
||||||
|
private Config _config
|
||||||
|
{
|
||||||
|
get => AppHandler.Instance.Config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<int, List<EGlobalHotkey>> _hotkeyTriggerDic;
|
||||||
|
|
||||||
public bool IsPause { get; set; } = false;
|
public bool IsPause { get; set; } = false;
|
||||||
|
|
||||||
|
|
@ -22,6 +29,7 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
public HotkeyHandler()
|
public HotkeyHandler()
|
||||||
{
|
{
|
||||||
|
_hotkeyTriggerDic = new();
|
||||||
ComponentDispatcher.ThreadPreprocessMessage += OnThreadPreProcessMessage;
|
ComponentDispatcher.ThreadPreprocessMessage += OnThreadPreProcessMessage;
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
@ -29,31 +37,20 @@ namespace v2rayN.Handler
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
_hotkeyTriggerDic.Clear();
|
_hotkeyTriggerDic.Clear();
|
||||||
if (AppHandler.Instance.Config.GlobalHotkeys == null)
|
if (_config.GlobalHotkeys == null)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
foreach (var item in _config.GlobalHotkeys)
|
||||||
foreach (var item in AppHandler.Instance.Config.GlobalHotkeys)
|
|
||||||
{
|
{
|
||||||
if (item.KeyCode != null && (Key)item.KeyCode != Key.None)
|
if (item.KeyCode != null && (Key)item.KeyCode != Key.None)
|
||||||
{
|
{
|
||||||
var key = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode);
|
int key = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode);
|
||||||
var modifiers = KeyModifiers.None;
|
KeyModifiers modifiers = KeyModifiers.None;
|
||||||
if (item.Control)
|
if (item.Control)
|
||||||
{
|
|
||||||
modifiers |= KeyModifiers.Ctrl;
|
modifiers |= KeyModifiers.Ctrl;
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Shift)
|
if (item.Shift)
|
||||||
{
|
|
||||||
modifiers |= KeyModifiers.Shift;
|
modifiers |= KeyModifiers.Shift;
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Alt)
|
if (item.Alt)
|
||||||
{
|
|
||||||
modifiers |= KeyModifiers.Alt;
|
modifiers |= KeyModifiers.Alt;
|
||||||
}
|
|
||||||
|
|
||||||
key = (key << 16) | (int)modifiers;
|
key = (key << 16) | (int)modifiers;
|
||||||
if (!_hotkeyTriggerDic.ContainsKey(key))
|
if (!_hotkeyTriggerDic.ContainsKey(key))
|
||||||
{
|
{
|
||||||
|
|
@ -62,21 +59,19 @@ namespace v2rayN.Handler
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!_hotkeyTriggerDic[key].Contains(item.EGlobalHotkey))
|
if (!_hotkeyTriggerDic[key].Contains(item.EGlobalHotkey))
|
||||||
{
|
|
||||||
_hotkeyTriggerDic[key].Add(item.EGlobalHotkey);
|
_hotkeyTriggerDic[key].Add(item.EGlobalHotkey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
foreach (var _hotkeyCode in _hotkeyTriggerDic.Keys)
|
foreach (var _hotkeyCode in _hotkeyTriggerDic.Keys)
|
||||||
{
|
{
|
||||||
var hotkeyInfo = GetHotkeyInfo(_hotkeyCode);
|
var hotkeyInfo = GetHotkeyInfo(_hotkeyCode);
|
||||||
var isSuccess = false;
|
bool isSuccess = false;
|
||||||
var msg = string.Empty;
|
string msg;
|
||||||
|
|
||||||
Application.Current?.Dispatcher.Invoke(() =>
|
Application.Current?.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
|
|
@ -111,38 +106,29 @@ namespace v2rayN.Handler
|
||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
private (int fsModifiers, int vKey, string hotkeyStr, List<string> Names) GetHotkeyInfo(int hotkeyCode)
|
private (int fsModifiers, int vKey, string hotkeyStr, List<string> Names) GetHotkeyInfo(int hotkeycode)
|
||||||
{
|
{
|
||||||
var fsModifiers = hotkeyCode & 0xffff;
|
var _fsModifiers = hotkeycode & 0xffff;
|
||||||
var vKey = (hotkeyCode >> 16) & 0xffff;
|
var _vkey = (hotkeycode >> 16) & 0xffff;
|
||||||
var hotkeyStr = new StringBuilder();
|
var _hotkeyStr = new StringBuilder();
|
||||||
var names = new List<string>();
|
var _names = new List<string>();
|
||||||
|
|
||||||
var modify = (KeyModifiers)fsModifiers;
|
var mdif = (KeyModifiers)_fsModifiers;
|
||||||
var key = KeyInterop.KeyFromVirtualKey(vKey);
|
var key = KeyInterop.KeyFromVirtualKey(_vkey);
|
||||||
if ((modify & KeyModifiers.Ctrl) == KeyModifiers.Ctrl)
|
if ((mdif & KeyModifiers.Ctrl) == KeyModifiers.Ctrl)
|
||||||
|
_hotkeyStr.Append($"{KeyModifiers.Ctrl}+");
|
||||||
|
if ((mdif & KeyModifiers.Alt) == KeyModifiers.Alt)
|
||||||
|
_hotkeyStr.Append($"{KeyModifiers.Alt}+");
|
||||||
|
if ((mdif & KeyModifiers.Shift) == KeyModifiers.Shift)
|
||||||
|
_hotkeyStr.Append($"{KeyModifiers.Shift}+");
|
||||||
|
_hotkeyStr.Append(key.ToString());
|
||||||
|
|
||||||
|
foreach (var name in _hotkeyTriggerDic[hotkeycode])
|
||||||
{
|
{
|
||||||
hotkeyStr.Append($"{KeyModifiers.Ctrl}+");
|
_names.Add(name.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((modify & KeyModifiers.Alt) == KeyModifiers.Alt)
|
return (_fsModifiers, _vkey, _hotkeyStr.ToString(), _names);
|
||||||
{
|
|
||||||
hotkeyStr.Append($"{KeyModifiers.Alt}+");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((modify & KeyModifiers.Shift) == KeyModifiers.Shift)
|
|
||||||
{
|
|
||||||
hotkeyStr.Append($"{KeyModifiers.Shift}+");
|
|
||||||
}
|
|
||||||
|
|
||||||
hotkeyStr.Append(key.ToString());
|
|
||||||
|
|
||||||
foreach (var name in _hotkeyTriggerDic[hotkeyCode])
|
|
||||||
{
|
|
||||||
names.Add(name.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return (fsModifiers, vKey, hotkeyStr.ToString(), names);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnThreadPreProcessMessage(ref MSG msg, ref bool handled)
|
private void OnThreadPreProcessMessage(ref MSG msg, ref bool handled)
|
||||||
|
|
@ -152,18 +138,21 @@ namespace v2rayN.Handler
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handled = true;
|
handled = true;
|
||||||
var hotKeyCode = (int)msg.lParam;
|
var _hotKeyCode = (int)msg.lParam;
|
||||||
if (IsPause)
|
if (IsPause)
|
||||||
{
|
{
|
||||||
Application.Current?.Dispatcher.Invoke(() =>
|
Application.Current?.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
if (Keyboard.FocusedElement is UIElement element)
|
UIElement? element = Keyboard.FocusedElement as UIElement;
|
||||||
|
if (element != null)
|
||||||
{
|
{
|
||||||
var keyEventArgs = new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromVisual(element), 0, KeyInterop.KeyFromVirtualKey(GetHotkeyInfo(hotKeyCode).vKey))
|
var _keyEventArgs = new KeyEventArgs(Keyboard.PrimaryDevice,
|
||||||
|
PresentationSource.FromVisual(element), 0,
|
||||||
|
KeyInterop.KeyFromVirtualKey(GetHotkeyInfo(_hotKeyCode).vKey))
|
||||||
{
|
{
|
||||||
RoutedEvent = UIElement.KeyDownEvent
|
RoutedEvent = UIElement.KeyDownEvent
|
||||||
};
|
};
|
||||||
element.RaiseEvent(keyEventArgs);
|
element.RaiseEvent(_keyEventArgs);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
<reactiveui:ReactiveWindow
|
<reactiveui:ReactiveWindow
|
||||||
x:Class="v2rayN.Views.GlobalHotkeySettingWindow"
|
x:Class="v2rayN.Views.GlobalHotkeySettingWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:reactiveui="http://reactiveui.net"
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
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.menuSetting}"
|
Title="{x:Static resx:ResUI.menuSetting}"
|
||||||
Width="700"
|
Width="700"
|
||||||
Height="500"
|
Height="500"
|
||||||
x:TypeArguments="vms:SubEditViewModel"
|
x:TypeArguments="vms:SubEditViewModel"
|
||||||
|
KeyDown="GlobalHotkeySettingWindow_KeyDown"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
Style="{StaticResource WindowGlobal}"
|
Style="{StaticResource WindowGlobal}"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ namespace v2rayN.Views
|
||||||
{
|
{
|
||||||
public partial class GlobalHotkeySettingWindow
|
public partial class GlobalHotkeySettingWindow
|
||||||
{
|
{
|
||||||
private static Config? _config;
|
private static Config _config = default!;
|
||||||
private Dictionary<object, KeyEventItem> _textBoxKeyEventItem = new();
|
private Dictionary<object, KeyEventItem> _TextBoxKeyEventItem = default!;
|
||||||
|
|
||||||
public GlobalHotkeySettingWindow()
|
public GlobalHotkeySettingWindow()
|
||||||
{
|
{
|
||||||
|
|
@ -17,7 +17,7 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
this.Owner = Application.Current.MainWindow;
|
this.Owner = Application.Current.MainWindow;
|
||||||
_config = AppHandler.Instance.Config;
|
_config = AppHandler.Instance.Config;
|
||||||
_config.GlobalHotkeys ??= new();
|
_config.GlobalHotkeys ??= new List<KeyEventItem>();
|
||||||
|
|
||||||
btnReset.Click += btnReset_Click;
|
btnReset.Click += btnReset_Click;
|
||||||
btnSave.Click += btnSave_ClickAsync;
|
btnSave.Click += btnSave_ClickAsync;
|
||||||
|
|
@ -36,7 +36,7 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
private void InitData()
|
private void InitData()
|
||||||
{
|
{
|
||||||
_textBoxKeyEventItem = new()
|
_TextBoxKeyEventItem = new()
|
||||||
{
|
{
|
||||||
{ txtGlobalHotkey0,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.ShowForm) },
|
{ txtGlobalHotkey0,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.ShowForm) },
|
||||||
{ txtGlobalHotkey1,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxyClear) },
|
{ txtGlobalHotkey1,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxyClear) },
|
||||||
|
|
@ -44,32 +44,24 @@ namespace v2rayN.Views
|
||||||
{ txtGlobalHotkey3,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxyUnchanged)},
|
{ txtGlobalHotkey3,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxyUnchanged)},
|
||||||
{ txtGlobalHotkey4,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxyPac)}
|
{ txtGlobalHotkey4,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxyPac)}
|
||||||
};
|
};
|
||||||
|
|
||||||
BindingData();
|
BindingData();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TxtGlobalHotkey_PreviewKeyDown(object? sender, KeyEventArgs e)
|
private void TxtGlobalHotkey_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
if (sender is null)
|
var _ModifierKeys = new Key[] { Key.LeftCtrl, Key.RightCtrl, Key.LeftShift,
|
||||||
{
|
Key.RightShift, Key.LeftAlt, Key.RightAlt, Key.LWin, Key.RWin};
|
||||||
return;
|
_TextBoxKeyEventItem[sender].KeyCode = (int)(e.Key == Key.System ? (_ModifierKeys.Contains(e.SystemKey) ? Key.None : e.SystemKey) : (_ModifierKeys.Contains(e.Key) ? Key.None : e.Key));
|
||||||
|
_TextBoxKeyEventItem[sender].Alt = (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt;
|
||||||
|
_TextBoxKeyEventItem[sender].Control = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;
|
||||||
|
_TextBoxKeyEventItem[sender].Shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
|
||||||
|
(sender as TextBox)!.Text = KeyEventItemToString(_TextBoxKeyEventItem[sender]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var item = _textBoxKeyEventItem[sender];
|
private KeyEventItem GetKeyEventItemByEGlobalHotkey(List<KeyEventItem> KEList, EGlobalHotkey eg)
|
||||||
var modifierKeys = new Key[] { Key.LeftCtrl, Key.RightCtrl, Key.LeftShift, Key.RightShift, Key.LeftAlt, Key.RightAlt, Key.LWin, Key.RWin };
|
|
||||||
|
|
||||||
item.KeyCode = (int)(e.Key == Key.System ? (modifierKeys.Contains(e.SystemKey) ? Key.None : e.SystemKey) : (modifierKeys.Contains(e.Key) ? Key.None : e.Key));
|
|
||||||
item.Alt = (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt;
|
|
||||||
item.Control = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;
|
|
||||||
item.Shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
|
|
||||||
|
|
||||||
(sender as TextBox)!.Text = KeyEventItemToString(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private KeyEventItem GetKeyEventItemByEGlobalHotkey(List<KeyEventItem> lstKey, EGlobalHotkey eg)
|
|
||||||
{
|
{
|
||||||
return JsonUtils.DeepCopy(lstKey.Find((it) => it.EGlobalHotkey == eg) ?? new()
|
return JsonUtils.DeepCopy(KEList.Find((it) => it.EGlobalHotkey == eg) ?? new()
|
||||||
{
|
{
|
||||||
EGlobalHotkey = eg,
|
EGlobalHotkey = eg,
|
||||||
Control = false,
|
Control = false,
|
||||||
|
|
@ -84,31 +76,20 @@ namespace v2rayN.Views
|
||||||
var res = new StringBuilder();
|
var res = new StringBuilder();
|
||||||
|
|
||||||
if (item.Control)
|
if (item.Control)
|
||||||
{
|
|
||||||
res.Append($"{ModifierKeys.Control}+");
|
res.Append($"{ModifierKeys.Control}+");
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Shift)
|
if (item.Shift)
|
||||||
{
|
|
||||||
res.Append($"{ModifierKeys.Shift}+");
|
res.Append($"{ModifierKeys.Shift}+");
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Alt)
|
if (item.Alt)
|
||||||
{
|
|
||||||
res.Append($"{ModifierKeys.Alt}+");
|
res.Append($"{ModifierKeys.Alt}+");
|
||||||
}
|
|
||||||
|
|
||||||
if (item.KeyCode != null && (Key)item.KeyCode != Key.None)
|
if (item.KeyCode != null && (Key)item.KeyCode != Key.None)
|
||||||
{
|
|
||||||
res.Append($"{(Key)item.KeyCode}");
|
res.Append($"{(Key)item.KeyCode}");
|
||||||
}
|
|
||||||
|
|
||||||
return res.ToString();
|
return res.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BindingData()
|
private void BindingData()
|
||||||
{
|
{
|
||||||
foreach (var item in _textBoxKeyEventItem)
|
foreach (var item in _TextBoxKeyEventItem)
|
||||||
{
|
{
|
||||||
if (item.Value.KeyCode != null && (Key)item.Value.KeyCode != Key.None)
|
if (item.Value.KeyCode != null && (Key)item.Value.KeyCode != Key.None)
|
||||||
{
|
{
|
||||||
|
|
@ -123,7 +104,7 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
private async void btnSave_ClickAsync(object sender, RoutedEventArgs e)
|
private async void btnSave_ClickAsync(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_config.GlobalHotkeys = _textBoxKeyEventItem.Values.ToList();
|
_config.GlobalHotkeys = _TextBoxKeyEventItem.Values.ToList();
|
||||||
|
|
||||||
if (await ConfigHandler.SaveConfig(_config) == 0)
|
if (await ConfigHandler.SaveConfig(_config) == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -138,16 +119,22 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
private void btnReset_Click(object sender, RoutedEventArgs e)
|
private void btnReset_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
foreach (var k in _textBoxKeyEventItem.Keys)
|
foreach (var k in _TextBoxKeyEventItem.Keys)
|
||||||
{
|
{
|
||||||
var item = _textBoxKeyEventItem[k];
|
_TextBoxKeyEventItem[k].Alt = false;
|
||||||
|
_TextBoxKeyEventItem[k].Control = false;
|
||||||
item.Alt = false;
|
_TextBoxKeyEventItem[k].Shift = false;
|
||||||
item.Control = false;
|
_TextBoxKeyEventItem[k].KeyCode = (int)Key.None;
|
||||||
item.Shift = false;
|
|
||||||
item.KeyCode = (int)Key.None;
|
|
||||||
}
|
}
|
||||||
BindingData();
|
BindingData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GlobalHotkeySettingWindow_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Key == Key.Escape)
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue