Skip to content

Commit 697fb72

Browse files
authored
Merge pull request #3392 from Flow-Launcher/fix_dispatcher_issue
Fix application null exception & Remove unused MainWindowOpacity property
2 parents 21ddd70 + c64e16d commit 697fb72

File tree

3 files changed

+39
-30
lines changed

3 files changed

+39
-30
lines changed

Flow.Launcher/MainWindow.xaml

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
Left="{Binding Settings.WindowLeft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
2525
Loaded="OnLoaded"
2626
LocationChanged="OnLocationChanged"
27-
Opacity="{Binding MainWindowOpacity, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
2827
PreviewKeyDown="OnKeyDown"
2928
PreviewKeyUp="OnKeyUp"
3029
PreviewMouseMove="OnPreviewMouseMove"

Flow.Launcher/MainWindow.xaml.cs

+30-23
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
111111
App.API.SaveAppAllSettings();
112112

113113
// Show Welcome Window
114-
var WelcomeWindow = new WelcomeWindow();
115-
WelcomeWindow.Show();
114+
var welcomeWindow = new WelcomeWindow();
115+
welcomeWindow.Show();
116116
}
117117

118118
// Hide window if need
@@ -241,7 +241,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
241241
};
242242

243243
// QueryTextBox.Text change detection (modified to only work when character count is 1 or higher)
244-
QueryTextBox.TextChanged += (sender, e) => UpdateClockPanelVisibility();
244+
QueryTextBox.TextChanged += (s, e) => UpdateClockPanelVisibility();
245245

246246
// Detecting ContextMenu.Visibility changes
247247
DependencyPropertyDescriptor
@@ -351,15 +351,13 @@ private void OnKeyDown(object sender, KeyEventArgs e)
351351
_viewModel.LoadContextMenuCommand.Execute(null);
352352
e.Handled = true;
353353
}
354-
355354
break;
356355
case Key.Left:
357356
if (!_viewModel.QueryResultsSelected() && QueryTextBox.CaretIndex == 0)
358357
{
359358
_viewModel.EscCommand.Execute(null);
360359
e.Handled = true;
361360
}
362-
363361
break;
364362
case Key.Back:
365363
if (specialKeyState.CtrlPressed)
@@ -378,7 +376,6 @@ private void OnKeyDown(object sender, KeyEventArgs e)
378376
}
379377
}
380378
}
381-
382379
break;
383380
default:
384381
break;
@@ -864,16 +861,18 @@ private void WindowAnimation()
864861
private void UpdateClockPanelVisibility()
865862
{
866863
if (QueryTextBox == null || ContextMenu == null || History == null || ClockPanel == null)
864+
{
867865
return;
866+
}
868867

868+
// ✅ Initialize animation length & duration
869869
var animationLength = _settings.AnimationSpeed switch
870870
{
871871
AnimationSpeeds.Slow => 560,
872872
AnimationSpeeds.Medium => 360,
873873
AnimationSpeeds.Fast => 160,
874874
_ => _settings.CustomAnimationLength
875875
};
876-
877876
var animationDuration = TimeSpan.FromMilliseconds(animationLength * 2 / 3);
878877

879878
// ✅ Conditions for showing ClockPanel (No query input & ContextMenu, History are closed)
@@ -890,15 +889,21 @@ private void UpdateClockPanelVisibility()
890889
}
891890

892891
// ✅ 2. When ContextMenu is closed, keep it Hidden if there's text in the query (remember previous state)
893-
if (ContextMenu.Visibility != Visibility.Visible && QueryTextBox.Text.Length > 0)
892+
else if (QueryTextBox.Text.Length > 0)
894893
{
895894
_viewModel.ClockPanelVisibility = Visibility.Hidden;
896895
_viewModel.ClockPanelOpacity = 0.0;
897896
return;
898897
}
899898

899+
// ✅ Prevent multiple animations
900+
if (_isClockPanelAnimating)
901+
{
902+
return;
903+
}
904+
900905
// ✅ 3. When hiding ClockPanel (apply fade-out animation)
901-
if ((!shouldShowClock) && _viewModel.ClockPanelVisibility == Visibility.Visible && !_isClockPanelAnimating)
906+
if ((!shouldShowClock) && _viewModel.ClockPanelVisibility == Visibility.Visible)
902907
{
903908
_isClockPanelAnimating = true;
904909

@@ -920,32 +925,32 @@ private void UpdateClockPanelVisibility()
920925
}
921926

922927
// ✅ 4. When showing ClockPanel (apply fade-in animation)
923-
else if (shouldShowClock && _viewModel.ClockPanelVisibility != Visibility.Visible && !_isClockPanelAnimating)
928+
else if (shouldShowClock && _viewModel.ClockPanelVisibility != Visibility.Visible)
924929
{
925930
_isClockPanelAnimating = true;
926931

927-
Application.Current.Dispatcher.Invoke(() =>
932+
_viewModel.ClockPanelVisibility = Visibility.Visible; // ✅ Set Visibility to Visible first
933+
934+
var fadeIn = new DoubleAnimation
928935
{
929-
_viewModel.ClockPanelVisibility = Visibility.Visible; // ✅ Set Visibility to Visible first
936+
From = 0.0,
937+
To = 1.0,
938+
Duration = animationDuration,
939+
FillBehavior = FillBehavior.HoldEnd
940+
};
930941

931-
var fadeIn = new DoubleAnimation
932-
{
933-
From = 0.0,
934-
To = 1.0,
935-
Duration = animationDuration,
936-
FillBehavior = FillBehavior.HoldEnd
937-
};
938-
939-
fadeIn.Completed += (s, e) => _isClockPanelAnimating = false;
940-
ClockPanel.BeginAnimation(OpacityProperty, fadeIn);
941-
}, DispatcherPriority.Render);
942+
fadeIn.Completed += (s, e) => _isClockPanelAnimating = false;
943+
944+
ClockPanel.BeginAnimation(OpacityProperty, fadeIn);
942945
}
943946
}
944947

945948
private static double GetOpacityFromStyle(Style style, double defaultOpacity = 1.0)
946949
{
947950
if (style == null)
951+
{
948952
return defaultOpacity;
953+
}
949954

950955
foreach (Setter setter in style.Setters.Cast<Setter>())
951956
{
@@ -961,7 +966,9 @@ private static double GetOpacityFromStyle(Style style, double defaultOpacity = 1
961966
private static Thickness GetThicknessFromStyle(Style style, Thickness defaultThickness)
962967
{
963968
if (style == null)
969+
{
964970
return defaultThickness;
971+
}
965972

966973
foreach (Setter setter in style.Setters.Cast<Setter>())
967974
{

Flow.Launcher/ViewModel/MainViewModel.cs

+9-6
Original file line numberDiff line numberDiff line change
@@ -753,8 +753,7 @@ private ResultsViewModel SelectedResults
753753

754754
public Visibility ProgressBarVisibility { get; set; }
755755
public Visibility MainWindowVisibility { get; set; }
756-
public double MainWindowOpacity { get; set; } = 1;
757-
756+
758757
// This is to be used for determining the visibility status of the mainwindow instead of MainWindowVisibility
759758
// because it is more accurate and reliable representation than using Visibility as a condition check
760759
public bool MainWindowVisibilityStatus { get; set; } = true;
@@ -1454,9 +1453,11 @@ public bool ShouldIgnoreHotkeys()
14541453

14551454
public void Show()
14561455
{
1456+
// Invoke on UI thread
14571457
Application.Current.Dispatcher.Invoke(() =>
14581458
{
1459-
if (Application.Current.MainWindow is MainWindow mainWindow)
1459+
// When application is exitting, the Application.Current will be null
1460+
if (Application.Current?.MainWindow is MainWindow mainWindow)
14601461
{
14611462
// 📌 Remove DWM Cloak (Make the window visible normally)
14621463
Win32Helper.DWMSetCloakForWindow(mainWindow, false);
@@ -1481,10 +1482,10 @@ public void Show()
14811482

14821483
// Update WPF properties
14831484
MainWindowVisibility = Visibility.Visible;
1484-
MainWindowOpacity = 1;
14851485
MainWindowVisibilityStatus = true;
14861486
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });
14871487

1488+
// Switch keyboard layout
14881489
if (StartWithEnglishMode)
14891490
{
14901491
Win32Helper.SwitchToEnglishKeyboardLayout(true);
@@ -1527,9 +1528,11 @@ public async void Hide()
15271528
break;
15281529
}
15291530

1531+
// Invoke on UI thread
15301532
Application.Current.Dispatcher.Invoke(() =>
15311533
{
1532-
if (Application.Current.MainWindow is MainWindow mainWindow)
1534+
// When application is exitting, the Application.Current will be null
1535+
if (Application.Current?.MainWindow is MainWindow mainWindow)
15331536
{
15341537
// Set clock and search icon opacity
15351538
var opacity = Settings.UseAnimation ? 0.0 : 1.0;
@@ -1549,6 +1552,7 @@ public async void Hide()
15491552
}
15501553
}, DispatcherPriority.Render);
15511554

1555+
// Switch keyboard layout
15521556
if (StartWithEnglishMode)
15531557
{
15541558
Win32Helper.RestorePreviousKeyboardLayout();
@@ -1558,7 +1562,6 @@ public async void Hide()
15581562
await Task.Delay(50);
15591563

15601564
// Update WPF properties
1561-
//MainWindowOpacity = 0;
15621565
MainWindowVisibilityStatus = false;
15631566
MainWindowVisibility = Visibility.Collapsed;
15641567
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });

0 commit comments

Comments
 (0)