|
12 | 12 | using Flow.Launcher.Infrastructure.Logger; |
13 | 13 | using Flow.Launcher.Infrastructure.UserSettings; |
14 | 14 | using System.Windows.Shell; |
| 15 | +using static Flow.Launcher.Core.Resource.Theme.ParameterTypes; |
| 16 | +using System.Runtime.InteropServices; |
| 17 | +using System.Windows.Interop; |
15 | 18 |
|
16 | 19 | namespace Flow.Launcher.Core.Resource |
17 | 20 | { |
@@ -59,6 +62,153 @@ public Theme() |
59 | 62 | _oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath); |
60 | 63 | } |
61 | 64 |
|
| 65 | + #region Blur Handling |
| 66 | + public class ParameterTypes |
| 67 | + { |
| 68 | + |
| 69 | + [Flags] |
| 70 | + public enum DWMWINDOWATTRIBUTE |
| 71 | + { |
| 72 | + DWMWA_USE_IMMERSIVE_DARK_MODE = 20, |
| 73 | + DWMWA_SYSTEMBACKDROP_TYPE = 38, |
| 74 | + DWMWA_TRANSITIONS_FORCEDISABLED = 3, |
| 75 | + DWMWA_BORDER_COLOR |
| 76 | + } |
| 77 | + |
| 78 | + [StructLayout(LayoutKind.Sequential)] |
| 79 | + public struct MARGINS |
| 80 | + { |
| 81 | + public int cxLeftWidth; // width of left border that retains its size |
| 82 | + public int cxRightWidth; // width of right border that retains its size |
| 83 | + public int cyTopHeight; // height of top border that retains its size |
| 84 | + public int cyBottomHeight; // height of bottom border that retains its size |
| 85 | + }; |
| 86 | + } |
| 87 | + |
| 88 | + public static class Methods |
| 89 | + { |
| 90 | + [DllImport("DwmApi.dll")] |
| 91 | + static extern int DwmExtendFrameIntoClientArea( |
| 92 | + IntPtr hwnd, |
| 93 | + ref ParameterTypes.MARGINS pMarInset); |
| 94 | + |
| 95 | + [DllImport("dwmapi.dll")] |
| 96 | + static extern int DwmSetWindowAttribute(IntPtr hwnd, ParameterTypes.DWMWINDOWATTRIBUTE dwAttribute, ref int pvAttribute, int cbAttribute); |
| 97 | + |
| 98 | + public static int ExtendFrame(IntPtr hwnd, ParameterTypes.MARGINS margins) |
| 99 | + => DwmExtendFrameIntoClientArea(hwnd, ref margins); |
| 100 | + |
| 101 | + public static int SetWindowAttribute(IntPtr hwnd, ParameterTypes.DWMWINDOWATTRIBUTE attribute, int parameter) |
| 102 | + => DwmSetWindowAttribute(hwnd, attribute, ref parameter, Marshal.SizeOf<int>()); |
| 103 | + } |
| 104 | + |
| 105 | + Window mainWindow = Application.Current.MainWindow; |
| 106 | + |
| 107 | + public void RefreshFrame() |
| 108 | + { |
| 109 | + IntPtr mainWindowPtr = new WindowInteropHelper(mainWindow).Handle; |
| 110 | + HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr); |
| 111 | + //mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 255, 181, 178); |
| 112 | + |
| 113 | + ParameterTypes.MARGINS margins = new ParameterTypes.MARGINS(); |
| 114 | + margins.cxLeftWidth = -1; |
| 115 | + margins.cxRightWidth = -1; |
| 116 | + margins.cyTopHeight = -1; |
| 117 | + margins.cyBottomHeight = -1; |
| 118 | + Methods.ExtendFrame(mainWindowSrc.Handle, margins); |
| 119 | + |
| 120 | + // Remove OS minimizing/maximizing animation |
| 121 | + Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 3); |
| 122 | + //Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_BORDER_COLOR, 0x00FF0000); |
| 123 | + Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3); |
| 124 | + SetBlurForWindow(); |
| 125 | + } |
| 126 | + |
| 127 | + |
| 128 | + |
| 129 | + /// <summary> |
| 130 | + /// Sets the blur for a window via SetWindowCompositionAttribute |
| 131 | + /// </summary> |
| 132 | + public void SetBlurForWindow() |
| 133 | + { |
| 134 | + //SetWindowAccent(); |
| 135 | + var dict = GetThemeResourceDictionary(Settings.Theme); |
| 136 | + var windowBorderStyle = dict["WindowBorderStyle"] as Style; |
| 137 | + if (BlurEnabled) |
| 138 | + { |
| 139 | + windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property.Name == "Background")); |
| 140 | + windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent))); |
| 141 | + //mainWindow.WindowStyle = WindowStyle.SingleBorderWindow; |
| 142 | + Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 3); |
| 143 | + BlurColor(BlurMode()); |
| 144 | + } |
| 145 | + else |
| 146 | + { |
| 147 | + mainWindow.WindowStyle = WindowStyle.None; |
| 148 | + if (windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property.Name == "Background") != null) |
| 149 | + { |
| 150 | + windowBorderStyle.Setters.Add(windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property.Name == "Background")); |
| 151 | + } |
| 152 | + Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_SYSTEMBACKDROP_TYPE, 1); |
| 153 | + } |
| 154 | + UpdateResourceDictionary(dict); |
| 155 | + } |
| 156 | + |
| 157 | + public void BlurColor(string Color) |
| 158 | + { |
| 159 | + if (Color == "Light") |
| 160 | + { |
| 161 | + Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0); |
| 162 | + } |
| 163 | + else if (Color == "Dark") |
| 164 | + { |
| 165 | + Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1); |
| 166 | + } |
| 167 | + else /* Case of "Auto" Blur Type Theme */ |
| 168 | + { |
| 169 | + //if (_isDarkTheme()) |
| 170 | + //{ |
| 171 | + // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1); |
| 172 | + //} |
| 173 | + //else |
| 174 | + //{ |
| 175 | + // Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 0); |
| 176 | + //} |
| 177 | + Methods.SetWindowAttribute(new WindowInteropHelper(mainWindow).Handle, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, 1); |
| 178 | + } |
| 179 | + |
| 180 | + } |
| 181 | + public bool IsBlurTheme() |
| 182 | + { |
| 183 | + if (Environment.OSVersion.Version >= new Version(6, 2)) |
| 184 | + { |
| 185 | + var resource = Application.Current.TryFindResource("ThemeBlurEnabled"); |
| 186 | + |
| 187 | + if (resource is bool) |
| 188 | + return (bool)resource; |
| 189 | + |
| 190 | + return false; |
| 191 | + } |
| 192 | + |
| 193 | + return false; |
| 194 | + } |
| 195 | + public string BlurMode() |
| 196 | + { |
| 197 | + if (Environment.OSVersion.Version >= new Version(6, 2)) |
| 198 | + { |
| 199 | + var resource = Application.Current.TryFindResource("BlurMode"); |
| 200 | + |
| 201 | + if (resource is string) |
| 202 | + return (string)resource; |
| 203 | + |
| 204 | + return null; |
| 205 | + } |
| 206 | + |
| 207 | + return null; |
| 208 | + } |
| 209 | + |
| 210 | + #endregion |
| 211 | + |
62 | 212 | private void MakeSureThemeDirectoriesExist() |
63 | 213 | { |
64 | 214 | foreach (var dir in _themeDirectories.Where(dir => !Directory.Exists(dir))) |
@@ -103,6 +253,7 @@ public bool ChangeTheme(string theme) |
103 | 253 | AddDropShadowEffectToCurrentTheme(); |
104 | 254 |
|
105 | 255 | Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled); |
| 256 | + //Win32Helper.SetMicaForWindow(Application.Current.MainWindow, BlurEnabled); |
106 | 257 | } |
107 | 258 | catch (DirectoryNotFoundException) |
108 | 259 | { |
|
0 commit comments