mirror of
https://github.com/Stone-Red-Code/InvLock.git
synced 2026-09-04 09:06:13 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a53be9abe | ||
|
|
f0dbf4621b | ||
|
|
28eeac5635 | ||
|
|
6350903d96 | ||
|
|
a13babb780 | ||
|
|
beb6fce41a | ||
|
|
3c39d693fa | ||
|
|
b065b90f87 |
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -3,7 +3,7 @@
|
||||
## Usage
|
||||
|
||||
1. Download & install the latest release
|
||||
- Microsoft Store: [Store Page (Coming Soon)](https://www.microsoft.com/store/apps)
|
||||
- Microsoft Store: [Store Page](https://apps.microsoft.com/detail/9P5ZXZQJRK4H?hl=en-us&gl=AT&ocid=pdpshare)
|
||||
- GitHub: [Releases](https://github.com/Stone-Red-Code/InvLock/releases)
|
||||
2. (Optional) Put a shortcut to the `InvLock.exe` file in the installation directory into the `shell:startup` directory.
|
||||
3. Start the app and configure the settings to your liking.
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[Setup]
|
||||
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||
AppId=68d780d4-b946-4154-8815-e4632e5ec5d8
|
||||
AppId=4B2411E5-1AE9-450C-AF2F-9A515ECBB9DF
|
||||
AppName={#MyAppName}
|
||||
AppVersion={#MyAppVersion}
|
||||
;AppVerName={#MyAppName} {#MyAppVersion}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
<Window x:Class="InvLock.BlurWindow"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:InvLock"
|
||||
mc:Ignorable="d"
|
||||
Loaded="Window_Loaded"
|
||||
WindowStyle="None"
|
||||
MouseDown="Window_MouseDown"
|
||||
AllowsTransparency="True"
|
||||
Background="Black"
|
||||
Opacity="0"
|
||||
Title="BlurWindow" Height="450" Width="800">
|
||||
</Window>
|
||||
@@ -0,0 +1,26 @@
|
||||
using InvLock.Utilities;
|
||||
|
||||
using System.Windows;
|
||||
|
||||
namespace InvLock;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for BlurWindow.xaml
|
||||
/// </summary>
|
||||
public partial class BlurWindow : Window
|
||||
{
|
||||
public BlurWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WindowsApi.EnableBlur(this);
|
||||
}
|
||||
|
||||
private void Window_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
DragMove();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
using InvLock.Utilities;
|
||||
|
||||
using SharpHook.Native;
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace InvLock.DataContexts;
|
||||
|
||||
internal partial class MainWindowDataContext(Func<LockWindow?> lockWindowAccessor)
|
||||
internal partial class MainWindowDataContext(Func<LockWindow?> lockWindowAccessor) : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
#if DEBUG
|
||||
public string Title => $"{App.AppName} - Dev {AppVersion}";
|
||||
#else
|
||||
@@ -16,10 +22,28 @@ internal partial class MainWindowDataContext(Func<LockWindow?> lockWindowAccesso
|
||||
|
||||
public string AppName => App.AppName;
|
||||
|
||||
public string AppVersion => Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "Unknown";
|
||||
public string AppVersion => Assembly.GetEntryAssembly()?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "Unknown";
|
||||
|
||||
public Settings Settings { get; } = Settings.Load();
|
||||
|
||||
public bool IsAutoStartEnabled
|
||||
{
|
||||
get => StartupManager.IsAutoStartEnabled();
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
_ = StartupManager.EnableAutoStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = StartupManager.DisableAutoStart();
|
||||
}
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public async Task RecordLockShortcut()
|
||||
{
|
||||
@@ -55,4 +79,9 @@ internal partial class MainWindowDataContext(Func<LockWindow?> lockWindowAccesso
|
||||
Settings.UnlockShortcut = unlockShortcut;
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnPropertyChanged([CallerMemberName] string? name = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,10 @@
|
||||
<UseWPF>true</UseWPF>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<ApplicationIcon>Assets\logo.ico</ApplicationIcon>
|
||||
<Version>1.1.0.0</Version>
|
||||
<AssemblyVersion>1.1.0.0</AssemblyVersion>
|
||||
<FileVersion>1.1.0.0</FileVersion>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -17,9 +21,11 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="CuteUtils" Version="1.0.0" />
|
||||
<PackageReference Include="Interop.IWshRuntimeLibrary" Version="1.0.1" />
|
||||
<PackageReference Include="SharpHook" Version="5.3.8" />
|
||||
<PackageReference Include="WPF-UI" Version="4.0.0" />
|
||||
<PackageReference Include="WPF-UI.Tray" Version="4.0.0" />
|
||||
<PackageReference Include="WpfScreenHelper" Version="2.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -19,7 +19,9 @@ public partial class LockWindow : Window
|
||||
private readonly SimpleGlobalHook hook = new SimpleGlobalHook();
|
||||
private readonly Dictionary<KeyCode, DateTime> pressedKeys = [];
|
||||
private readonly Settings settings;
|
||||
private readonly List<BlurWindow> blurWindows = [];
|
||||
private List<IntPtr> windows = [];
|
||||
private Point lastMousePosition;
|
||||
private bool isOpen = true;
|
||||
private bool suppressInput = false;
|
||||
|
||||
@@ -120,11 +122,32 @@ public partial class LockWindow : Window
|
||||
MinimizeWindows();
|
||||
}
|
||||
|
||||
isOpen = true;
|
||||
suppressInput = true;
|
||||
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
lastMousePosition = WpfScreenHelper.MouseHelper.MousePosition;
|
||||
|
||||
if (settings.BlurScreen)
|
||||
{
|
||||
foreach (Rect bounds in WpfScreenHelper.Screen.AllScreens.Select(s => s.WpfBounds))
|
||||
{
|
||||
BlurWindow blurWindow = new()
|
||||
{
|
||||
Width = bounds.Width,
|
||||
Height = bounds.Height,
|
||||
Left = bounds.Left,
|
||||
Top = bounds.Top,
|
||||
};
|
||||
|
||||
blurWindows.Add(blurWindow);
|
||||
blurWindow.Show();
|
||||
}
|
||||
|
||||
_ = WindowsApi.SetCursorPosition(new Point(100000, 100000));
|
||||
}
|
||||
|
||||
isOpen = true;
|
||||
suppressInput = true;
|
||||
|
||||
_ = Activate();
|
||||
|
||||
textBlock.Text = settings.LockText;
|
||||
@@ -155,6 +178,9 @@ public partial class LockWindow : Window
|
||||
|
||||
isOpen = true;
|
||||
|
||||
_ = WindowsApi.SetCursorPosition(lastMousePosition);
|
||||
blurWindows.ForEach(w => w.Close());
|
||||
|
||||
textBlock.Text = settings.UnlockText;
|
||||
textBlock.Stroke = (Brush)FindResource("PaletteGreenBrush");
|
||||
|
||||
@@ -203,6 +229,9 @@ public partial class LockWindow : Window
|
||||
|
||||
isOpen = true;
|
||||
|
||||
_ = WindowsApi.SetCursorPosition(lastMousePosition);
|
||||
blurWindows.ForEach(w => w.Close());
|
||||
|
||||
_ = Activate();
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
@@ -79,6 +79,20 @@
|
||||
</ComboBox>
|
||||
</ui:CardControl>
|
||||
|
||||
<ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=Clock24}" Height="75">
|
||||
<ui:CardControl.Header>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Run at startup" />
|
||||
<ui:TextBlock Grid.Row="1" Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" FontSize="12" Text="Start InvLock when you sign in to Windows" />
|
||||
</Grid>
|
||||
</ui:CardControl.Header>
|
||||
<ui:ToggleSwitch Grid.Column="1" IsChecked="{Binding IsAutoStartEnabled}" OffContent="Off" OnContent="On" />
|
||||
</ui:CardControl>
|
||||
|
||||
<ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=Window24}" Height="75">
|
||||
<ui:CardControl.Header>
|
||||
<ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Show desktop while locked" />
|
||||
@@ -86,6 +100,13 @@
|
||||
<ui:ToggleSwitch Grid.Column="1" IsChecked="{Binding Settings.HideWindows}" OffContent="Off" OnContent="On" />
|
||||
</ui:CardControl>
|
||||
|
||||
<ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=Blur24}" Height="75">
|
||||
<ui:CardControl.Header>
|
||||
<ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Blur screen while locked" />
|
||||
</ui:CardControl.Header>
|
||||
<ui:ToggleSwitch Grid.Column="1" IsChecked="{Binding Settings.BlurScreen}" OffContent="Off" OnContent="On" />
|
||||
</ui:CardControl>
|
||||
|
||||
<ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=WindowShield24}" Height="75">
|
||||
<ui:CardControl.Header>
|
||||
<ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Use windows lock screen to unlock" />
|
||||
|
||||
@@ -71,6 +71,7 @@ public partial class MainWindow : FluentWindow
|
||||
e.Cancel = true;
|
||||
|
||||
ShowInTaskbar = false;
|
||||
WindowState = WindowState.Minimized;
|
||||
Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ public class Settings : INotifyPropertyChanged
|
||||
private static readonly string settingsPath = Path.Combine(App.ApplicationDataPath, "settings.json");
|
||||
private bool useWindowsLockScreen = true;
|
||||
private bool hideWindows = false;
|
||||
private bool blurScreen = false;
|
||||
private string lockText = "Lock Screen Active";
|
||||
private string theme = "Windows default";
|
||||
private HashSet<KeyCode> lockShortcut = [KeyCode.VcLeftControl, KeyCode.VcLeftShift, KeyCode.VcL];
|
||||
@@ -34,6 +35,16 @@ public class Settings : INotifyPropertyChanged
|
||||
}
|
||||
}
|
||||
|
||||
public bool BlurScreen
|
||||
{
|
||||
get => blurScreen;
|
||||
set
|
||||
{
|
||||
blurScreen = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool UseWindowsLockScreen
|
||||
{
|
||||
get => useWindowsLockScreen;
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
using IWshRuntimeLibrary;
|
||||
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
|
||||
namespace InvLock.Utilities;
|
||||
|
||||
public enum AutoStartStatus
|
||||
{
|
||||
Success = 0,
|
||||
InvalidParameters = 1,
|
||||
AlreadyEnabled = 2,
|
||||
AlreadyDisabled = 3,
|
||||
UnexpectedError = 4
|
||||
}
|
||||
|
||||
public static class StartupManager
|
||||
{
|
||||
private static readonly string appPath = Path.ChangeExtension(Assembly.GetEntryAssembly()?.Location ?? throw new InvalidOperationException("Failed to get the application path."), ".exe");
|
||||
private static readonly string startupFolder = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
|
||||
private static readonly string shortcutPath = Path.Combine(startupFolder, Path.GetFileNameWithoutExtension(appPath) + ".lnk");
|
||||
|
||||
public static bool IsAutoStartEnabled()
|
||||
{
|
||||
return System.IO.File.Exists(shortcutPath);
|
||||
}
|
||||
|
||||
public static AutoStartStatus EnableAutoStart()
|
||||
{
|
||||
if (IsAutoStartEnabled())
|
||||
{
|
||||
return AutoStartStatus.AlreadyEnabled;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
WshShell shell = new WshShell();
|
||||
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);
|
||||
shortcut.TargetPath = appPath;
|
||||
shortcut.WorkingDirectory = Path.GetDirectoryName(appPath);
|
||||
shortcut.Save();
|
||||
return AutoStartStatus.Success;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return AutoStartStatus.UnexpectedError;
|
||||
}
|
||||
}
|
||||
|
||||
public static AutoStartStatus DisableAutoStart()
|
||||
{
|
||||
if (!IsAutoStartEnabled())
|
||||
{
|
||||
return AutoStartStatus.AlreadyDisabled;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
System.IO.File.Delete(shortcutPath);
|
||||
return AutoStartStatus.Success;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return AutoStartStatus.UnexpectedError;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ToggleAutoStart()
|
||||
{
|
||||
AutoStartStatus status = IsAutoStartEnabled() ? DisableAutoStart() : EnableAutoStart();
|
||||
|
||||
_ = status switch
|
||||
{
|
||||
AutoStartStatus.Success => MessageBox.Show("Auto-start setting changed successfully."),
|
||||
AutoStartStatus.AlreadyEnabled => MessageBox.Show("Auto-start is already enabled."),
|
||||
AutoStartStatus.AlreadyDisabled => MessageBox.Show("Auto-start is already disabled."),
|
||||
_ => MessageBox.Show("Failed to change auto-start setting."),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace InvLock.Utilities;
|
||||
|
||||
@@ -70,12 +72,46 @@ public static class WindowsApi
|
||||
_ = ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
|
||||
}
|
||||
|
||||
public static bool SetCursorPosition(Point point)
|
||||
{
|
||||
return SetCursorPos((int)point.X, (int)point.Y);
|
||||
}
|
||||
|
||||
public static void EnableBlur(Window window)
|
||||
{
|
||||
WindowInteropHelper windowHelper = new WindowInteropHelper(window);
|
||||
|
||||
AccentPolicy accent = new AccentPolicy
|
||||
{
|
||||
AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND
|
||||
};
|
||||
|
||||
int accentStructSize = Marshal.SizeOf(accent);
|
||||
|
||||
nint accentPtr = Marshal.AllocHGlobal(accentStructSize);
|
||||
Marshal.StructureToPtr(accent, accentPtr, false);
|
||||
|
||||
WindowCompositionAttributeData data = new WindowCompositionAttributeData
|
||||
{
|
||||
Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
|
||||
SizeOfData = accentStructSize,
|
||||
Data = accentPtr
|
||||
};
|
||||
|
||||
_ = SetWindowCompositionAttribute(windowHelper.Handle, ref data);
|
||||
|
||||
Marshal.FreeHGlobal(accentPtr);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool LockWorkStation();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
|
||||
|
||||
@@ -102,4 +138,41 @@ public static class WindowsApi
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool IsIconic(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetCursorPos(int x, int y);
|
||||
|
||||
internal enum AccentState
|
||||
{
|
||||
ACCENT_DISABLED = 1,
|
||||
ACCENT_ENABLE_GRADIENT = 0,
|
||||
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
|
||||
ACCENT_ENABLE_BLURBEHIND = 3,
|
||||
ACCENT_INVALID_STATE = 4
|
||||
}
|
||||
|
||||
internal enum WindowCompositionAttribute
|
||||
{
|
||||
// ...
|
||||
WCA_ACCENT_POLICY = 19
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct AccentPolicy
|
||||
{
|
||||
public AccentState AccentState;
|
||||
public int AccentFlags;
|
||||
public int GradientColor;
|
||||
public int AnimationId;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct WindowCompositionAttributeData
|
||||
{
|
||||
public WindowCompositionAttribute Attribute;
|
||||
public IntPtr Data;
|
||||
public int SizeOfData;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user