Fix first-time window flicker & clock panel flicker issue

This commit is contained in:
Jack251970 2025-03-28 16:13:02 +08:00
parent 8a08e03cf9
commit 693ba52fbc
2 changed files with 61 additions and 47 deletions

View file

@ -166,22 +166,6 @@ namespace Flow.Launcher
{ {
if (_viewModel.MainWindowVisibilityStatus) if (_viewModel.MainWindowVisibilityStatus)
{ {
// Set clock and search icon opacity
var opacity = _settings.UseAnimation ? 0.0 : 1.0;
ClockPanel.Opacity = opacity;
SearchIcon.Opacity = opacity;
// Set clock and search icon visibility
ClockPanel.Visibility = string.IsNullOrEmpty(_viewModel.QueryText) ? Visibility.Visible : Visibility.Collapsed;
if (_viewModel.PluginIconSource != null)
{
SearchIcon.Opacity = 0.0;
}
else
{
_viewModel.SearchIconVisibility = Visibility.Visible;
}
// Play sound effect before activing the window // Play sound effect before activing the window
if (_settings.UseSound) if (_settings.UseSound)
{ {
@ -214,21 +198,6 @@ namespace Flow.Launcher
// Update activate times // Update activate times
_settings.ActivateTimes++; _settings.ActivateTimes++;
} }
else
{
// Set clock and search icon opacity
var opacity = _settings.UseAnimation ? 0.0 : 1.0;
ClockPanel.Opacity = opacity;
SearchIcon.Opacity = opacity;
// Set clock and search icon visibility
ClockPanel.Visibility = Visibility.Hidden;
_viewModel.SearchIconVisibility = Visibility.Hidden;
// Force UI update
ClockPanel.UpdateLayout();
SearchIcon.UpdateLayout();
}
}); });
break; break;
} }
@ -329,8 +298,8 @@ namespace Flow.Launcher
_settings.WindowLeft = Left; _settings.WindowLeft = Left;
_settings.WindowTop = Top; _settings.WindowTop = Top;
ClockPanel.Opacity = 0.0; _viewModel.ClockPanelOpacity = 0.0;
SearchIcon.Opacity = 0.0; _viewModel.SearchIconOpacity = 0.0;
// This condition stops extra hide call when animator is on, // This condition stops extra hide call when animator is on,
// which causes the toggling to occasional hide instead of show. // which causes the toggling to occasional hide instead of show.
@ -908,28 +877,28 @@ namespace Flow.Launcher
var animationDuration = TimeSpan.FromMilliseconds(animationLength * 2 / 3); var animationDuration = TimeSpan.FromMilliseconds(animationLength * 2 / 3);
// ✅ Conditions for showing ClockPanel (No query input & ContextMenu, History are closed) // ✅ Conditions for showing ClockPanel (No query input & ContextMenu, History are closed)
bool shouldShowClock = QueryTextBox.Text.Length == 0 && var shouldShowClock = QueryTextBox.Text.Length == 0 &&
ContextMenu.Visibility != Visibility.Visible && ContextMenu.Visibility != Visibility.Visible &&
History.Visibility != Visibility.Visible; History.Visibility != Visibility.Visible;
// ✅ 1. When ContextMenu opens, immediately set Visibility.Hidden (force hide without animation) // ✅ 1. When ContextMenu opens, immediately set Visibility.Hidden (force hide without animation)
if (ContextMenu.Visibility == Visibility.Visible) if (ContextMenu.Visibility == Visibility.Visible)
{ {
ClockPanel.Visibility = Visibility.Hidden; _viewModel.ClockPanelVisibility = Visibility.Hidden;
ClockPanel.Opacity = 0.0; // Set to 0 in case Opacity animation affects it _viewModel.ClockPanelOpacity = 0.0; // Set to 0 in case Opacity animation affects it
return; return;
} }
// ✅ 2. When ContextMenu is closed, keep it Hidden if there's text in the query (remember previous state) // ✅ 2. When ContextMenu is closed, keep it Hidden if there's text in the query (remember previous state)
if (ContextMenu.Visibility != Visibility.Visible && QueryTextBox.Text.Length > 0) if (ContextMenu.Visibility != Visibility.Visible && QueryTextBox.Text.Length > 0)
{ {
ClockPanel.Visibility = Visibility.Hidden; _viewModel.ClockPanelVisibility = Visibility.Hidden;
ClockPanel.Opacity = 0.0; _viewModel.ClockPanelOpacity = 0.0;
return; return;
} }
// ✅ 3. When hiding ClockPanel (apply fade-out animation) // ✅ 3. When hiding ClockPanel (apply fade-out animation)
if ((!shouldShowClock) && ClockPanel.Visibility == Visibility.Visible && !_isClockPanelAnimating) if ((!shouldShowClock) && _viewModel.ClockPanelVisibility == Visibility.Visible && !_isClockPanelAnimating)
{ {
_isClockPanelAnimating = true; _isClockPanelAnimating = true;
@ -943,7 +912,7 @@ namespace Flow.Launcher
fadeOut.Completed += (s, e) => fadeOut.Completed += (s, e) =>
{ {
ClockPanel.Visibility = Visibility.Hidden; // ✅ Completely hide after animation _viewModel.ClockPanelVisibility = Visibility.Hidden; // ✅ Completely hide after animation
_isClockPanelAnimating = false; _isClockPanelAnimating = false;
}; };
@ -951,13 +920,13 @@ namespace Flow.Launcher
} }
// ✅ 4. When showing ClockPanel (apply fade-in animation) // ✅ 4. When showing ClockPanel (apply fade-in animation)
else if (shouldShowClock && ClockPanel.Visibility != Visibility.Visible && !_isClockPanelAnimating) else if (shouldShowClock && _viewModel.ClockPanelVisibility != Visibility.Visible && !_isClockPanelAnimating)
{ {
_isClockPanelAnimating = true; _isClockPanelAnimating = true;
Application.Current.Dispatcher.Invoke(() => Application.Current.Dispatcher.Invoke(() =>
{ {
ClockPanel.Visibility = Visibility.Visible; // ✅ Set Visibility to Visible first _viewModel.ClockPanelVisibility = Visibility.Visible; // ✅ Set Visibility to Visible first
var fadeIn = new DoubleAnimation var fadeIn = new DoubleAnimation
{ {

View file

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.DependencyInjection; using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using Flow.Launcher.Core.Plugin; using Flow.Launcher.Core.Plugin;
@ -1453,8 +1454,30 @@ namespace Flow.Launcher.ViewModel
public void Show() public void Show()
{ {
// 📌 Remove DWM Cloak (Make the window visible normally) Application.Current.Dispatcher.Invoke(() =>
Win32Helper.DWMSetCloakForWindow(Application.Current.MainWindow, false); {
if (Application.Current.MainWindow is MainWindow mainWindow)
{
// 📌 Remove DWM Cloak (Make the window visible normally)
Win32Helper.DWMSetCloakForWindow(mainWindow, false);
// Set clock and search icon opacity
var opacity = Settings.UseAnimation ? 0.0 : 1.0;
ClockPanelOpacity = opacity;
SearchIconOpacity = opacity;
// Set clock and search icon visibility
ClockPanelVisibility = string.IsNullOrEmpty(QueryText) ? Visibility.Visible : Visibility.Collapsed;
if (PluginIconSource != null)
{
SearchIconOpacity = 0.0;
}
else
{
SearchIconVisibility = Visibility.Visible;
}
}
}, DispatcherPriority.Render);
// Update WPF properties // Update WPF properties
MainWindowVisibility = Visibility.Visible; MainWindowVisibility = Visibility.Visible;
@ -1470,9 +1493,6 @@ namespace Flow.Launcher.ViewModel
public async void Hide() public async void Hide()
{ {
// 📌 Apply DWM Cloak (Completely hide the window)
Win32Helper.DWMSetCloakForWindow(Application.Current.MainWindow, true);
lastHistoryIndex = 1; lastHistoryIndex = 1;
if (ExternalPreviewVisible) if (ExternalPreviewVisible)
@ -1507,11 +1527,36 @@ namespace Flow.Launcher.ViewModel
break; break;
} }
Application.Current.Dispatcher.Invoke(() =>
{
if (Application.Current.MainWindow is MainWindow mainWindow)
{
// Set clock and search icon opacity
var opacity = Settings.UseAnimation ? 0.0 : 1.0;
ClockPanelOpacity = opacity;
SearchIconOpacity = opacity;
// Set clock and search icon visibility
ClockPanelVisibility = Visibility.Hidden;
SearchIconVisibility = Visibility.Hidden;
// Force UI update
mainWindow.ClockPanel.UpdateLayout();
mainWindow.SearchIcon.UpdateLayout();
// 📌 Apply DWM Cloak (Completely hide the window)
Win32Helper.DWMSetCloakForWindow(mainWindow, true);
}
}, DispatcherPriority.Render);
if (StartWithEnglishMode) if (StartWithEnglishMode)
{ {
Win32Helper.RestorePreviousKeyboardLayout(); Win32Helper.RestorePreviousKeyboardLayout();
} }
// Delay for a while to make sure clock will not flicker
await Task.Delay(50);
// Update WPF properties // Update WPF properties
//MainWindowOpacity = 0; //MainWindowOpacity = 0;
MainWindowVisibilityStatus = false; MainWindowVisibilityStatus = false;