@@ -101,13 +101,18 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
101
101
// Check first launch
102
102
if ( _settings . FirstLaunch )
103
103
{
104
+ // Set First Launch to false
104
105
_settings . FirstLaunch = false ;
106
+
107
+ // Set Backdrop Type to Acrylic for Windows 11 when First Launch. Default is None
108
+ if ( Win32Helper . IsBackdropSupported ( ) ) _settings . BackdropType = BackdropTypes . Acrylic ;
109
+
110
+ // Save settings
105
111
App . API . SaveAppAllSettings ( ) ;
106
- /* Set Backdrop Type to Acrylic for Windows 11 when First Launch. Default is None. */
107
- if ( OperatingSystem . IsWindowsVersionAtLeast ( 10 , 0 , 22000 ) )
108
- _settings . BackdropType = BackdropTypes . Acrylic ;
109
- var WelcomeWindow = new WelcomeWindow ( ) ;
110
- WelcomeWindow . Show ( ) ;
112
+
113
+ // Show Welcome Window
114
+ var welcomeWindow = new WelcomeWindow ( ) ;
115
+ welcomeWindow . Show ( ) ;
111
116
}
112
117
113
118
// Hide window if need
@@ -161,24 +166,37 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
161
166
{
162
167
if ( _viewModel . MainWindowVisibilityStatus )
163
168
{
169
+ // Play sound effect before activing the window
164
170
if ( _settings . UseSound )
165
171
{
166
172
SoundPlay ( ) ;
167
173
}
168
174
175
+ // Update position & Activate
169
176
UpdatePosition ( ) ;
170
- _viewModel . ResetPreview ( ) ;
171
177
Activate ( ) ;
172
- QueryTextBox . Focus ( ) ;
173
- _settings . ActivateTimes ++ ;
178
+
179
+ // Reset preview
180
+ _viewModel . ResetPreview ( ) ;
181
+
182
+ // Select last query if need
174
183
if ( ! _viewModel . LastQuerySelected )
175
184
{
176
185
QueryTextBox . SelectAll ( ) ;
177
186
_viewModel . LastQuerySelected = true ;
178
187
}
179
188
189
+ // Focus query box
190
+ QueryTextBox . Focus ( ) ;
191
+
192
+ // Play window animation
180
193
if ( _settings . UseAnimation )
194
+ {
181
195
WindowAnimation ( ) ;
196
+ }
197
+
198
+ // Update activate times
199
+ _settings . ActivateTimes ++ ;
182
200
}
183
201
} ) ;
184
202
break ;
@@ -191,7 +209,6 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
191
209
Dispatcher . Invoke ( ( ) => QueryTextBox . CaretIndex = QueryTextBox . Text . Length ) ;
192
210
_viewModel . QueryTextCursorMovedToEnd = false ;
193
211
}
194
-
195
212
break ;
196
213
case nameof ( MainViewModel . GameModeStatus ) :
197
214
_notifyIcon . Icon = _viewModel . GameModeStatus
@@ -224,7 +241,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
224
241
} ;
225
242
226
243
// QueryTextBox.Text change detection (modified to only work when character count is 1 or higher)
227
- QueryTextBox . TextChanged += ( sender , e ) => UpdateClockPanelVisibility ( ) ;
244
+ QueryTextBox . TextChanged += ( s , e ) => UpdateClockPanelVisibility ( ) ;
228
245
229
246
// Detecting ContextMenu.Visibility changes
230
247
DependencyPropertyDescriptor
@@ -248,7 +265,8 @@ private async void OnClosing(object sender, CancelEventArgs e)
248
265
Notification . Uninstall ( ) ;
249
266
// After plugins are all disposed, we can close the main window
250
267
_canClose = true ;
251
- Close ( ) ;
268
+ // Use this instead of Close() to avoid InvalidOperationException when calling Close() in OnClosing event
269
+ Application . Current . Shutdown ( ) ;
252
270
}
253
271
}
254
272
@@ -280,8 +298,8 @@ private async void OnDeactivated(object sender, EventArgs e)
280
298
_settings . WindowLeft = Left ;
281
299
_settings . WindowTop = Top ;
282
300
283
- ClockPanel . Opacity = 0 ;
284
- SearchIcon . Opacity = 0 ;
301
+ _viewModel . ClockPanelOpacity = 0. 0;
302
+ _viewModel . SearchIconOpacity = 0. 0;
285
303
286
304
// This condition stops extra hide call when animator is on,
287
305
// which causes the toggling to occasional hide instead of show.
@@ -291,7 +309,9 @@ private async void OnDeactivated(object sender, EventArgs e)
291
309
// This also stops the mainwindow from flickering occasionally after Settings window is opened
292
310
// and always after Settings window is closed.
293
311
if ( _settings . UseAnimation )
312
+ {
294
313
await Task . Delay ( 100 ) ;
314
+ }
295
315
296
316
if ( _settings . HideWhenDeactivated && ! _viewModel . ExternalPreviewVisible )
297
317
{
@@ -331,15 +351,13 @@ private void OnKeyDown(object sender, KeyEventArgs e)
331
351
_viewModel . LoadContextMenuCommand . Execute ( null ) ;
332
352
e . Handled = true ;
333
353
}
334
-
335
354
break ;
336
355
case Key . Left :
337
356
if ( ! _viewModel . QueryResultsSelected ( ) && QueryTextBox . CaretIndex == 0 )
338
357
{
339
358
_viewModel . EscCommand . Execute ( null ) ;
340
359
e . Handled = true ;
341
360
}
342
-
343
361
break ;
344
362
case Key . Back :
345
363
if ( specialKeyState . CtrlPressed )
@@ -358,7 +376,6 @@ private void OnKeyDown(object sender, KeyEventArgs e)
358
376
}
359
377
}
360
378
}
361
-
362
379
break ;
363
380
default :
364
381
break ;
@@ -765,12 +782,6 @@ private void WindowAnimation()
765
782
{
766
783
_isArrowKeyPressed = true ;
767
784
768
- UpdatePosition ( ) ;
769
-
770
- var opacity = _settings . UseAnimation ? 0.0 : 1.0 ;
771
- ClockPanel . Opacity = opacity ;
772
- SearchIcon . Opacity = opacity ;
773
-
774
785
var clocksb = new Storyboard ( ) ;
775
786
var iconsb = new Storyboard ( ) ;
776
787
var easing = new CircleEase { EasingMode = EasingMode . EaseInOut } ;
@@ -850,41 +861,49 @@ private void WindowAnimation()
850
861
private void UpdateClockPanelVisibility ( )
851
862
{
852
863
if ( QueryTextBox == null || ContextMenu == null || History == null || ClockPanel == null )
864
+ {
853
865
return ;
866
+ }
854
867
868
+ // ✅ Initialize animation length & duration
855
869
var animationLength = _settings . AnimationSpeed switch
856
870
{
857
871
AnimationSpeeds . Slow => 560 ,
858
872
AnimationSpeeds . Medium => 360 ,
859
873
AnimationSpeeds . Fast => 160 ,
860
874
_ => _settings . CustomAnimationLength
861
875
} ;
862
-
863
876
var animationDuration = TimeSpan . FromMilliseconds ( animationLength * 2 / 3 ) ;
864
877
865
878
// ✅ Conditions for showing ClockPanel (No query input & ContextMenu, History are closed)
866
- bool shouldShowClock = QueryTextBox . Text . Length == 0 &&
879
+ var shouldShowClock = QueryTextBox . Text . Length == 0 &&
867
880
ContextMenu . Visibility != Visibility . Visible &&
868
881
History . Visibility != Visibility . Visible ;
869
882
870
883
// ✅ 1. When ContextMenu opens, immediately set Visibility.Hidden (force hide without animation)
871
884
if ( ContextMenu . Visibility == Visibility . Visible )
872
885
{
873
- ClockPanel . Visibility = Visibility . Hidden ;
874
- ClockPanel . Opacity = 0.0 ; // Set to 0 in case Opacity animation affects it
886
+ _viewModel . ClockPanelVisibility = Visibility . Hidden ;
887
+ _viewModel . ClockPanelOpacity = 0.0 ; // Set to 0 in case Opacity animation affects it
875
888
return ;
876
889
}
877
890
878
891
// ✅ 2. When ContextMenu is closed, keep it Hidden if there's text in the query (remember previous state)
879
- if ( ContextMenu . Visibility != Visibility . Visible && QueryTextBox . Text . Length > 0 )
892
+ else if ( QueryTextBox . Text . Length > 0 )
893
+ {
894
+ _viewModel . ClockPanelVisibility = Visibility . Hidden ;
895
+ _viewModel . ClockPanelOpacity = 0.0 ;
896
+ return ;
897
+ }
898
+
899
+ // ✅ Prevent multiple animations
900
+ if ( _isClockPanelAnimating )
880
901
{
881
- ClockPanel . Visibility = Visibility . Hidden ;
882
- ClockPanel . Opacity = 0.0 ;
883
902
return ;
884
903
}
885
904
886
905
// ✅ 3. When hiding ClockPanel (apply fade-out animation)
887
- if ( ( ! shouldShowClock ) && ClockPanel . Visibility == Visibility . Visible && ! _isClockPanelAnimating )
906
+ if ( ( ! shouldShowClock ) && _viewModel . ClockPanelVisibility == Visibility . Visible )
888
907
{
889
908
_isClockPanelAnimating = true ;
890
909
@@ -898,40 +917,40 @@ private void UpdateClockPanelVisibility()
898
917
899
918
fadeOut . Completed += ( s , e ) =>
900
919
{
901
- ClockPanel . Visibility = Visibility . Hidden ; // ✅ Completely hide after animation
920
+ _viewModel . ClockPanelVisibility = Visibility . Hidden ; // ✅ Completely hide after animation
902
921
_isClockPanelAnimating = false ;
903
922
} ;
904
923
905
924
ClockPanel . BeginAnimation ( OpacityProperty , fadeOut ) ;
906
925
}
926
+
907
927
// ✅ 4. When showing ClockPanel (apply fade-in animation)
908
- else if ( shouldShowClock && ClockPanel . Visibility != Visibility . Visible && ! _isClockPanelAnimating )
928
+ else if ( shouldShowClock && _viewModel . ClockPanelVisibility != Visibility . Visible )
909
929
{
910
930
_isClockPanelAnimating = true ;
911
931
912
- Application . Current . Dispatcher . Invoke ( ( ) =>
932
+ _viewModel . ClockPanelVisibility = Visibility . Visible ; // ✅ Set Visibility to Visible first
933
+
934
+ var fadeIn = new DoubleAnimation
913
935
{
914
- ClockPanel . Visibility = Visibility . Visible ; // ✅ Set Visibility to Visible first
936
+ From = 0.0 ,
937
+ To = 1.0 ,
938
+ Duration = animationDuration ,
939
+ FillBehavior = FillBehavior . HoldEnd
940
+ } ;
915
941
916
- var fadeIn = new DoubleAnimation
917
- {
918
- From = 0.0 ,
919
- To = 1.0 ,
920
- Duration = animationDuration ,
921
- FillBehavior = FillBehavior . HoldEnd
922
- } ;
923
-
924
- fadeIn . Completed += ( s , e ) => _isClockPanelAnimating = false ;
925
- ClockPanel . BeginAnimation ( OpacityProperty , fadeIn ) ;
926
- } , DispatcherPriority . Render ) ;
942
+ fadeIn . Completed += ( s , e ) => _isClockPanelAnimating = false ;
943
+
944
+ ClockPanel . BeginAnimation ( OpacityProperty , fadeIn ) ;
927
945
}
928
946
}
929
947
930
-
931
948
private static double GetOpacityFromStyle ( Style style , double defaultOpacity = 1.0 )
932
949
{
933
950
if ( style == null )
951
+ {
934
952
return defaultOpacity ;
953
+ }
935
954
936
955
foreach ( Setter setter in style . Setters . Cast < Setter > ( ) )
937
956
{
@@ -947,7 +966,9 @@ private static double GetOpacityFromStyle(Style style, double defaultOpacity = 1
947
966
private static Thickness GetThicknessFromStyle ( Style style , Thickness defaultThickness )
948
967
{
949
968
if ( style == null )
969
+ {
950
970
return defaultThickness ;
971
+ }
951
972
952
973
foreach ( Setter setter in style . Setters . Cast < Setter > ( ) )
953
974
{
0 commit comments