From 6350903d96cca2bdfccb6813fa60b67e668b4041 Mon Sep 17 00:00:00 2001 From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com> Date: Wed, 5 Mar 2025 17:40:05 +0100 Subject: [PATCH] Add screen blur option --- src/InvLock/BlurWindow.xaml | 15 ++++++ src/InvLock/BlurWindow.xaml.cs | 26 ++++++++++ src/InvLock/LockWindow.xaml.cs | 35 ++++++++++++-- src/InvLock/MainWindow.xaml | 21 +++++++++ src/InvLock/Settings.cs | 11 +++++ src/InvLock/Utilities/WindowsApi.cs | 73 +++++++++++++++++++++++++++++ 6 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 src/InvLock/BlurWindow.xaml create mode 100644 src/InvLock/BlurWindow.xaml.cs diff --git a/src/InvLock/BlurWindow.xaml b/src/InvLock/BlurWindow.xaml new file mode 100644 index 0000000..749ff8d --- /dev/null +++ b/src/InvLock/BlurWindow.xaml @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/src/InvLock/BlurWindow.xaml.cs b/src/InvLock/BlurWindow.xaml.cs new file mode 100644 index 0000000..dbde331 --- /dev/null +++ b/src/InvLock/BlurWindow.xaml.cs @@ -0,0 +1,26 @@ +using InvLock.Utilities; + +using System.Windows; + +namespace InvLock; + +/// +/// Interaction logic for BlurWindow.xaml +/// +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(); + } +} \ No newline at end of file diff --git a/src/InvLock/LockWindow.xaml.cs b/src/InvLock/LockWindow.xaml.cs index 67c4750..1677755 100644 --- a/src/InvLock/LockWindow.xaml.cs +++ b/src/InvLock/LockWindow.xaml.cs @@ -19,7 +19,9 @@ public partial class LockWindow : Window private readonly SimpleGlobalHook hook = new SimpleGlobalHook(); private readonly Dictionary pressedKeys = []; private readonly Settings settings; + private readonly List blurWindows = []; private List 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); diff --git a/src/InvLock/MainWindow.xaml b/src/InvLock/MainWindow.xaml index 6ff43a4..b213e80 100644 --- a/src/InvLock/MainWindow.xaml +++ b/src/InvLock/MainWindow.xaml @@ -79,6 +79,20 @@ + + + + + + + + + + + + + + @@ -86,6 +100,13 @@ + + + + + + + diff --git a/src/InvLock/Settings.cs b/src/InvLock/Settings.cs index 24c960e..4a057d6 100644 --- a/src/InvLock/Settings.cs +++ b/src/InvLock/Settings.cs @@ -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 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; diff --git a/src/InvLock/Utilities/WindowsApi.cs b/src/InvLock/Utilities/WindowsApi.cs index e8cd4db..681046e 100644 --- a/src/InvLock/Utilities/WindowsApi.cs +++ b/src/InvLock/Utilities/WindowsApi.cs @@ -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; + } } \ No newline at end of file