diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index a66104103..588acbdf8 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -530,7 +530,7 @@ namespace Flow.Launcher // πŸ“Œ 항상 같은 μœ„μΉ˜μ—μ„œ μ‹œμž‘ν•˜λ„λ‘ `_originalTop`을 μ‚¬μš© var WindowMotion = new DoubleAnimation { - From = Top + 10, // μ›λž˜ μœ„μΉ˜μ—μ„œ 10px λ‚΄λ €μ˜¨ ν›„ + From = Top, // μ›λž˜ μœ„μΉ˜μ—μ„œ 10px λ‚΄λ €μ˜¨ ν›„ To = Top, // λ‹€μ‹œ μ›λž˜ μœ„μΉ˜λ‘œ 이동 Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3), FillBehavior = FillBehavior.Stop diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 8caac5ec4..aa3682810 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -27,6 +27,8 @@ using Flow.Launcher.Infrastructure.Image; using System.Windows.Media; using CommunityToolkit.Mvvm.DependencyInjection; using System.Windows.Threading; +using System.Runtime.InteropServices; +using System.Windows.Interop; namespace Flow.Launcher.ViewModel { @@ -1381,28 +1383,46 @@ namespace Flow.Launcher.ViewModel } } + // DWM κ΄€λ ¨ μƒμˆ˜ + private const int DWMWA_CLOAK = 14; + private const int SW_HIDE = 0; + private const int SW_SHOW = 5; + + [DllImport("user32.dll")] + private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); + + [DllImport("dwmapi.dll")] + private static extern int DwmSetWindowAttribute(IntPtr hwnd, int dwAttribute, ref int pvAttribute, int cbAttribute); + public void Show() { Application.Current.Dispatcher.Invoke(() => { - MainWindowVisibility = Visibility.Visible; - MainWindowOpacity = 1; + if (Application.Current.MainWindow is MainWindow mainWindow) + { + IntPtr hWnd = new WindowInteropHelper(mainWindow).Handle; + // πŸ“Œ 창을 λ¨Όμ € 보이게 μ„€μ • + ShowWindow(hWnd, SW_SHOW); + + // πŸ“Œ DWM Cloak ν•΄μ œ (μ¦‰μ‹œ ν‘œμ‹œ) + int cloak = 0; + DwmSetWindowAttribute(hWnd, DWMWA_CLOAK, ref cloak, sizeof(int)); + } + + // WPF 속성 μ—…λ°μ΄νŠΈ + //MainWindowOpacity = 1; MainWindowVisibilityStatus = true; VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true }); }); } - public void Hide() + public async void Hide() { - // MainWindow μΈμŠ€ν„΄μŠ€λ₯Ό κ°€μ Έμ™€μ„œ μ• λ‹ˆλ©”μ΄μ…˜ μ΄ˆκΈ°ν™” - if (Application.Current.MainWindow is MainWindow mainWindow) - { - mainWindow.ResetAnimation(); // μ• λ‹ˆλ©”μ΄μ…˜ κ°•μ œ 리셋 - } - lastHistoryIndex = 1; - MainWindowOpacity = 0; + + // Trick for no delay + //MainWindowOpacity = 0; if (ExternalPreviewVisible) CloseExternalPreview(); @@ -1412,45 +1432,55 @@ namespace Flow.Launcher.ViewModel SelectedResults = Results; } - Application.Current.Dispatcher.Invoke(() => + // πŸ“Œ ν…μŠ€νŠΈ μ΄ˆκΈ°ν™” μ¦‰μ‹œ 적용 + UI κ°•μ œ μ—…λ°μ΄νŠΈ + if (Settings.LastQueryMode == LastQueryMode.Empty) { - switch (Settings.LastQueryMode) + ChangeQueryText(string.Empty); + await Task.Delay(1); // ν•œ ν”„λ ˆμž„ ν›„ UIκ°€ λ°˜μ˜λ˜λ„λ‘ λŒ€κΈ° + Application.Current.Dispatcher.Invoke(() => { - case LastQueryMode.Empty: - ChangeQueryText(string.Empty); - break; + Application.Current.MainWindow.UpdateLayout(); // UI κ°•μ œ μ—…λ°μ΄νŠΈ + }); + } - case LastQueryMode.Preserved: - LastQuerySelected = true; - break; + switch (Settings.LastQueryMode) + { + case LastQueryMode.Preserved: + case LastQueryMode.Selected: + LastQuerySelected = (Settings.LastQueryMode == LastQueryMode.Preserved); + break; - case LastQueryMode.Selected: + case LastQueryMode.ActionKeywordPreserved: + case LastQueryMode.ActionKeywordSelected: + var newQuery = _lastQuery.ActionKeyword; + if (!string.IsNullOrEmpty(newQuery)) + newQuery += " "; + ChangeQueryText(newQuery); + + if (Settings.LastQueryMode == LastQueryMode.ActionKeywordSelected) LastQuerySelected = false; - break; + break; + } - case LastQueryMode.ActionKeywordPreserved: - case LastQueryMode.ActionKeywordSelected: - var newQuery = _lastQuery.ActionKeyword; - if (!string.IsNullOrEmpty(newQuery)) - newQuery += " "; - ChangeQueryText(newQuery); + // πŸ“Œ DWM Cloak을 μ‚¬μš©ν•˜μ—¬ μ°½ μˆ¨κΉ€ + if (Application.Current.MainWindow is MainWindow mainWindow) + { + IntPtr hWnd = new WindowInteropHelper(mainWindow).Handle; - if (Settings.LastQueryMode == LastQueryMode.ActionKeywordSelected) - LastQuerySelected = false; - break; - } + // πŸ“Œ DWM Cloak ν™œμ„±ν™” + int cloak = 1; + DwmSetWindowAttribute(hWnd, DWMWA_CLOAK, ref cloak, sizeof(int)); - Application.Current.MainWindow.UpdateLayout(); - }, DispatcherPriority.Render); + // πŸ“Œ 창을 μ™„μ „νžˆ μˆ¨κΉ€ (μž”μƒ λ°©μ§€) + ShowWindow(hWnd, SW_HIDE); + } + // WPF 속성 μ—…λ°μ΄νŠΈ MainWindowVisibilityStatus = false; - MainWindowVisibility = Visibility.Collapsed; VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false }); } - - /// /// Checks if Flow Launcher should ignore any hotkeys ///