From 70e7f82ff5f25f255171efe40151acfb68736fd6 Mon Sep 17 00:00:00 2001 From: DB p Date: Sun, 16 Mar 2025 18:10:45 +0900 Subject: [PATCH] Fix Blink --- Flow.Launcher/MainWindow.xaml.cs | 43 +++++++++++++++++------- Flow.Launcher/ViewModel/MainViewModel.cs | 29 ++++++++-------- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 04e7867b1..6087313c6 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -30,6 +30,8 @@ using Windows.Win32; using Window = System.Windows.Window; using System.Linq; using System.Windows.Shapes; +using ModernWpf.Controls.Primitives; +using System.Runtime.InteropServices; namespace Flow.Launcher { @@ -827,29 +829,44 @@ namespace Flow.Launcher public void HideStartup() { - //_viewModel.MainWindowOpacity = 0.2; /*Fix Render Blinking */ + IntPtr hwnd = new WindowInteropHelper(System.Windows.Application.Current.MainWindow).Handle; + if (_settings.HideOnStartup) { - // πŸ“Œ 졜초 μ‹€ν–‰ μ‹œ 창이 κΉœλΉ‘μ΄λŠ” 문제 λ°©μ§€ (μ™„μ „νžˆ 숨긴 μƒνƒœλ‘œ μ‹œμž‘) - //System.Windows.Application.Current.MainWindow.Visibility = Visibility.Hidden; + CloakWindow(System.Windows.Application.Current.MainWindow); - //Dispatcher.BeginInvoke((Action)(() => - //{ - // _viewModel.Hide(); - // System.Windows.Application.Current.MainWindow.Visibility = Visibility.Collapsed; - //}), DispatcherPriority.Background); - _viewModel.Hide(); + Dispatcher.BeginInvoke((Action)(() => + { + _viewModel.Hide(); + System.Windows.Application.Current.MainWindow.Visibility = Visibility.Collapsed; + }), DispatcherPriority.Background); } else { - // πŸ“Œ 졜초 μ‹€ν–‰ μ‹œ 그림자 효과λ₯Ό 미리 μ μš©ν•˜μ—¬ Show() ν•  λ•Œ λ Œλ”λ§μ΄ λŠλ €μ§€μ§€ μ•Šλ„λ‘ 함 - //ThemeManager.Instance.SetBlurForWindow(); - //ThemeManager.Instance.AutoDropShadow(); + UncloakWindow(System.Windows.Application.Current.MainWindow); _viewModel.Show(); - //_viewModel.MainWindowOpacity = 1; } } + private const int DWMWA_CLOAK = 13; + + [DllImport("dwmapi.dll")] + private static extern int DwmSetWindowAttribute(IntPtr hwnd, int dwAttribute, ref int pvAttribute, int cbAttribute); + + public static void CloakWindow(Window window) + { + IntPtr hwnd = new WindowInteropHelper(window).Handle; + int cloak = 1; + DwmSetWindowAttribute(hwnd, DWMWA_CLOAK, ref cloak, sizeof(int)); + } + + public static void UncloakWindow(Window window) + { + IntPtr hwnd = new WindowInteropHelper(window).Handle; + int cloak = 0; + DwmSetWindowAttribute(hwnd, DWMWA_CLOAK, ref cloak, sizeof(int)); + } + public Screen SelectedScreen() { Screen screen; diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 72ab1d0b6..cf0343319 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -28,6 +28,7 @@ using System.Windows.Media; using CommunityToolkit.Mvvm.DependencyInjection; using System.Windows.Threading; using System.Windows.Interop; +using System.Runtime.InteropServices; namespace Flow.Launcher.ViewModel { @@ -1388,12 +1389,13 @@ namespace Flow.Launcher.ViewModel { IntPtr hWnd = new WindowInteropHelper(mainWindow).Handle; - // πŸ“Œ 창을 보이도둝 μ„€μ • (Cloak μ‚¬μš© μ•ˆ 함) - //ShowWindow(hWnd, SW_SHOW); + // πŸ“Œ DWM Cloak ν•΄μ œ (창을 μ •μƒμ μœΌλ‘œ ν‘œμ‹œ) + int cloak = 0; + DwmSetWindowAttribute(hWnd, 13, ref cloak, sizeof(int)); // πŸ“Œ UI μš”μ†Œ 볡원 mainWindow.ClockPanel.Visibility = Visibility.Visible; - //mainWindow.SearchIcon.Visibility = Visibility.Visible; + mainWindow.ClockPanel.Opacity = 1; SearchIconVisibility = Visibility.Visible; } @@ -1419,13 +1421,14 @@ namespace Flow.Launcher.ViewModel if (Application.Current.MainWindow is MainWindow mainWindow) { - // πŸ“Œ μ•„μ΄μ½˜κ³Ό μ‹œκ³„ Opacityλ₯Ό 0으둜 μ„€μ •ν•˜κ³  Visibility.Hidden 적용 + IntPtr hWnd = new WindowInteropHelper(mainWindow).Handle; + + // πŸ“Œ UI μš”μ†Œ 숨기기 Application.Current.Dispatcher.Invoke(() => { mainWindow.ClockPanel.Opacity = 0; mainWindow.SearchIcon.Opacity = 0; mainWindow.ClockPanel.Visibility = Visibility.Hidden; - //mainWindow.SearchIcon.Visibility = Visibility.Hidden; SearchIconVisibility = Visibility.Hidden; // κ°•μ œ UI μ—…λ°μ΄νŠΈ @@ -1433,7 +1436,9 @@ namespace Flow.Launcher.ViewModel mainWindow.SearchIcon.UpdateLayout(); }, DispatcherPriority.Render); - //await Task.Delay(10); // UI 반영 λŒ€κΈ° + // πŸ“Œ DWM Cloak 적용 (창을 μ™„μ „νžˆ μˆ¨κΉ€) + int cloak = 1; + DwmSetWindowAttribute(hWnd, 13, ref cloak, sizeof(int)); } // πŸ“Œ ν…μŠ€νŠΈ μ΄ˆκΈ°ν™” μ¦‰μ‹œ 적용 + UI κ°•μ œ μ—…λ°μ΄νŠΈ @@ -1466,20 +1471,16 @@ namespace Flow.Launcher.ViewModel break; } - //if (Application.Current.MainWindow is MainWindow mainWindow2) - //{ - // IntPtr hWnd = new WindowInteropHelper(mainWindow2).Handle; - - // // πŸ“Œ Cloak을 μ‚¬μš©ν•˜μ§€ μ•Šκ³  일반적인 `ShowWindow(SW_HIDE)` μ‚¬μš© β†’ Mica/Acrylic μœ μ§€λ¨ - // ShowWindow(hWnd, SW_HIDE); - //} - // WPF 속성 μ—…λ°μ΄νŠΈ MainWindowVisibilityStatus = false; MainWindowVisibility = Visibility.Collapsed; VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false }); } + // πŸ“Œ DWM API μΆ”κ°€ (P/Invoke) + [DllImport("dwmapi.dll")] + private static extern int DwmSetWindowAttribute(IntPtr hwnd, int dwAttribute, ref int pvAttribute, int cbAttribute); + /// /// Checks if Flow Launcher should ignore any hotkeys ///