Skip to content

Commit 693ba52

Browse files
committed
Fix first-time window flicker & clock panel flicker issue
1 parent 8a08e03 commit 693ba52

File tree

2 files changed

+61
-47
lines changed

2 files changed

+61
-47
lines changed

Flow.Launcher/MainWindow.xaml.cs

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -166,22 +166,6 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
166166
{
167167
if (_viewModel.MainWindowVisibilityStatus)
168168
{
169-
// Set clock and search icon opacity
170-
var opacity = _settings.UseAnimation ? 0.0 : 1.0;
171-
ClockPanel.Opacity = opacity;
172-
SearchIcon.Opacity = opacity;
173-
174-
// Set clock and search icon visibility
175-
ClockPanel.Visibility = string.IsNullOrEmpty(_viewModel.QueryText) ? Visibility.Visible : Visibility.Collapsed;
176-
if (_viewModel.PluginIconSource != null)
177-
{
178-
SearchIcon.Opacity = 0.0;
179-
}
180-
else
181-
{
182-
_viewModel.SearchIconVisibility = Visibility.Visible;
183-
}
184-
185169
// Play sound effect before activing the window
186170
if (_settings.UseSound)
187171
{
@@ -214,21 +198,6 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
214198
// Update activate times
215199
_settings.ActivateTimes++;
216200
}
217-
else
218-
{
219-
// Set clock and search icon opacity
220-
var opacity = _settings.UseAnimation ? 0.0 : 1.0;
221-
ClockPanel.Opacity = opacity;
222-
SearchIcon.Opacity = opacity;
223-
224-
// Set clock and search icon visibility
225-
ClockPanel.Visibility = Visibility.Hidden;
226-
_viewModel.SearchIconVisibility = Visibility.Hidden;
227-
228-
// Force UI update
229-
ClockPanel.UpdateLayout();
230-
SearchIcon.UpdateLayout();
231-
}
232201
});
233202
break;
234203
}
@@ -329,8 +298,8 @@ private async void OnDeactivated(object sender, EventArgs e)
329298
_settings.WindowLeft = Left;
330299
_settings.WindowTop = Top;
331300

332-
ClockPanel.Opacity = 0.0;
333-
SearchIcon.Opacity = 0.0;
301+
_viewModel.ClockPanelOpacity = 0.0;
302+
_viewModel.SearchIconOpacity = 0.0;
334303

335304
// This condition stops extra hide call when animator is on,
336305
// which causes the toggling to occasional hide instead of show.
@@ -908,28 +877,28 @@ private void UpdateClockPanelVisibility()
908877
var animationDuration = TimeSpan.FromMilliseconds(animationLength * 2 / 3);
909878

910879
// ✅ Conditions for showing ClockPanel (No query input & ContextMenu, History are closed)
911-
bool shouldShowClock = QueryTextBox.Text.Length == 0 &&
880+
var shouldShowClock = QueryTextBox.Text.Length == 0 &&
912881
ContextMenu.Visibility != Visibility.Visible &&
913882
History.Visibility != Visibility.Visible;
914883

915884
// ✅ 1. When ContextMenu opens, immediately set Visibility.Hidden (force hide without animation)
916885
if (ContextMenu.Visibility == Visibility.Visible)
917886
{
918-
ClockPanel.Visibility = Visibility.Hidden;
919-
ClockPanel.Opacity = 0.0; // Set to 0 in case Opacity animation affects it
887+
_viewModel.ClockPanelVisibility = Visibility.Hidden;
888+
_viewModel.ClockPanelOpacity = 0.0; // Set to 0 in case Opacity animation affects it
920889
return;
921890
}
922891

923892
// ✅ 2. When ContextMenu is closed, keep it Hidden if there's text in the query (remember previous state)
924893
if (ContextMenu.Visibility != Visibility.Visible && QueryTextBox.Text.Length > 0)
925894
{
926-
ClockPanel.Visibility = Visibility.Hidden;
927-
ClockPanel.Opacity = 0.0;
895+
_viewModel.ClockPanelVisibility = Visibility.Hidden;
896+
_viewModel.ClockPanelOpacity = 0.0;
928897
return;
929898
}
930899

931900
// ✅ 3. When hiding ClockPanel (apply fade-out animation)
932-
if ((!shouldShowClock) && ClockPanel.Visibility == Visibility.Visible && !_isClockPanelAnimating)
901+
if ((!shouldShowClock) && _viewModel.ClockPanelVisibility == Visibility.Visible && !_isClockPanelAnimating)
933902
{
934903
_isClockPanelAnimating = true;
935904

@@ -943,21 +912,21 @@ private void UpdateClockPanelVisibility()
943912

944913
fadeOut.Completed += (s, e) =>
945914
{
946-
ClockPanel.Visibility = Visibility.Hidden; // ✅ Completely hide after animation
915+
_viewModel.ClockPanelVisibility = Visibility.Hidden; // ✅ Completely hide after animation
947916
_isClockPanelAnimating = false;
948917
};
949918

950919
ClockPanel.BeginAnimation(OpacityProperty, fadeOut);
951920
}
952921

953922
// ✅ 4. When showing ClockPanel (apply fade-in animation)
954-
else if (shouldShowClock && ClockPanel.Visibility != Visibility.Visible && !_isClockPanelAnimating)
923+
else if (shouldShowClock && _viewModel.ClockPanelVisibility != Visibility.Visible && !_isClockPanelAnimating)
955924
{
956925
_isClockPanelAnimating = true;
957926

958927
Application.Current.Dispatcher.Invoke(() =>
959928
{
960-
ClockPanel.Visibility = Visibility.Visible; // ✅ Set Visibility to Visible first
929+
_viewModel.ClockPanelVisibility = Visibility.Visible; // ✅ Set Visibility to Visible first
961930

962931
var fadeIn = new DoubleAnimation
963932
{

Flow.Launcher/ViewModel/MainViewModel.cs

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Windows;
1111
using System.Windows.Input;
1212
using System.Windows.Media;
13+
using System.Windows.Threading;
1314
using CommunityToolkit.Mvvm.DependencyInjection;
1415
using CommunityToolkit.Mvvm.Input;
1516
using Flow.Launcher.Core.Plugin;
@@ -1453,8 +1454,30 @@ public bool ShouldIgnoreHotkeys()
14531454

14541455
public void Show()
14551456
{
1456-
// 📌 Remove DWM Cloak (Make the window visible normally)
1457-
Win32Helper.DWMSetCloakForWindow(Application.Current.MainWindow, false);
1457+
Application.Current.Dispatcher.Invoke(() =>
1458+
{
1459+
if (Application.Current.MainWindow is MainWindow mainWindow)
1460+
{
1461+
// 📌 Remove DWM Cloak (Make the window visible normally)
1462+
Win32Helper.DWMSetCloakForWindow(mainWindow, false);
1463+
1464+
// Set clock and search icon opacity
1465+
var opacity = Settings.UseAnimation ? 0.0 : 1.0;
1466+
ClockPanelOpacity = opacity;
1467+
SearchIconOpacity = opacity;
1468+
1469+
// Set clock and search icon visibility
1470+
ClockPanelVisibility = string.IsNullOrEmpty(QueryText) ? Visibility.Visible : Visibility.Collapsed;
1471+
if (PluginIconSource != null)
1472+
{
1473+
SearchIconOpacity = 0.0;
1474+
}
1475+
else
1476+
{
1477+
SearchIconVisibility = Visibility.Visible;
1478+
}
1479+
}
1480+
}, DispatcherPriority.Render);
14581481

14591482
// Update WPF properties
14601483
MainWindowVisibility = Visibility.Visible;
@@ -1470,9 +1493,6 @@ public void Show()
14701493

14711494
public async void Hide()
14721495
{
1473-
// 📌 Apply DWM Cloak (Completely hide the window)
1474-
Win32Helper.DWMSetCloakForWindow(Application.Current.MainWindow, true);
1475-
14761496
lastHistoryIndex = 1;
14771497

14781498
if (ExternalPreviewVisible)
@@ -1507,11 +1527,36 @@ public async void Hide()
15071527
break;
15081528
}
15091529

1530+
Application.Current.Dispatcher.Invoke(() =>
1531+
{
1532+
if (Application.Current.MainWindow is MainWindow mainWindow)
1533+
{
1534+
// Set clock and search icon opacity
1535+
var opacity = Settings.UseAnimation ? 0.0 : 1.0;
1536+
ClockPanelOpacity = opacity;
1537+
SearchIconOpacity = opacity;
1538+
1539+
// Set clock and search icon visibility
1540+
ClockPanelVisibility = Visibility.Hidden;
1541+
SearchIconVisibility = Visibility.Hidden;
1542+
1543+
// Force UI update
1544+
mainWindow.ClockPanel.UpdateLayout();
1545+
mainWindow.SearchIcon.UpdateLayout();
1546+
1547+
// 📌 Apply DWM Cloak (Completely hide the window)
1548+
Win32Helper.DWMSetCloakForWindow(mainWindow, true);
1549+
}
1550+
}, DispatcherPriority.Render);
1551+
15101552
if (StartWithEnglishMode)
15111553
{
15121554
Win32Helper.RestorePreviousKeyboardLayout();
15131555
}
15141556

1557+
// Delay for a while to make sure clock will not flicker
1558+
await Task.Delay(50);
1559+
15151560
// Update WPF properties
15161561
//MainWindowOpacity = 0;
15171562
MainWindowVisibilityStatus = false;

0 commit comments

Comments
 (0)