anshdadhich commited on
Commit
7ddbcdc
·
verified ·
1 Parent(s): c3699e5

Upload FastSeekWpf/MainWindow.xaml.cs

Browse files
Files changed (1) hide show
  1. FastSeekWpf/MainWindow.xaml.cs +82 -21
FastSeekWpf/MainWindow.xaml.cs CHANGED
@@ -36,6 +36,10 @@ public partial class MainWindow : Window, INotifyPropertyChanged
36
  private bool _initialized;
37
  private bool _isVisible;
38
 
 
 
 
 
39
  public event PropertyChangedEventHandler? PropertyChanged;
40
 
41
  private List<ResultItem> _results = new();
@@ -55,10 +59,30 @@ public partial class MainWindow : Window, INotifyPropertyChanged
55
  Loaded += (s, e) =>
56
  {
57
  var helper = new WindowInteropHelper(this);
58
- HwndSource.FromHwnd(helper.Handle)?.AddHook(WndProc);
 
 
 
 
59
  };
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  private void Window_Loaded(object sender, RoutedEventArgs e)
63
  {
64
  if (_initialized) return;
@@ -305,13 +329,15 @@ public partial class MainWindow : Window, INotifyPropertyChanged
305
  SearchBox.Focus();
306
  }
307
 
308
- // -- Search --
309
 
310
  private void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
311
  {
312
  var query = SearchBox.Text.Trim();
 
313
  if (string.IsNullOrEmpty(query))
314
  {
 
315
  Dispatcher.Invoke(() =>
316
  {
317
  Results = new List<ResultItem>();
@@ -320,33 +346,67 @@ public partial class MainWindow : Window, INotifyPropertyChanged
320
  return;
321
  }
322
 
323
- List<SearchResult> results;
324
- lock (_indexLock)
 
 
325
  {
326
- results = SearchEngine.Search(_index, query, 50, _caseSensitive, _excludedDirs);
327
  }
328
 
329
- var items = results.Select((r, i) => new ResultItem
 
330
  {
331
- FullPath = r.FullPath,
332
- DisplayName = Path.GetFileNameWithoutExtension(r.FullPath),
333
- IsSelected = i == 0,
334
- IsHovered = false,
335
- Kind = r.Kind,
336
- IconGlyph = GetIconGlyph(r.Kind),
337
- BadgeLabel = GetBadgeLabel(r.Kind),
338
- BadgeColor = GetBadgeColor(r.Kind)
339
- }).ToList();
340
 
341
- Dispatcher.Invoke(() =>
342
- {
343
- _selectedIndex = 0;
344
- Results = items;
345
- UpdateVisibility();
346
- StatusText.Text = $"{items.Count} results";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
  });
348
  }
349
 
 
 
 
 
 
 
 
 
 
 
350
  private void UpdateVisibility()
351
  {
352
  bool hasResults = Results.Count > 0;
@@ -452,6 +512,7 @@ public partial class MainWindow : Window, INotifyPropertyChanged
452
  protected override void OnClosing(CancelEventArgs e)
453
  {
454
  _cts?.Cancel();
 
455
  foreach (var w in _watchers) w.Dispose();
456
  _watchers.Clear();
457
  CacheManager.SaveCache(_index);
 
36
  private bool _initialized;
37
  private bool _isVisible;
38
 
39
+ // Debounced search
40
+ private CancellationTokenSource? _searchDebounceCts;
41
+ private readonly object _searchLock = new();
42
+
43
  public event PropertyChangedEventHandler? PropertyChanged;
44
 
45
  private List<ResultItem> _results = new();
 
59
  Loaded += (s, e) =>
60
  {
61
  var helper = new WindowInteropHelper(this);
62
+ var hwnd = helper.Handle;
63
+ HwndSource.FromHwnd(hwnd)?.AddHook(WndProc);
64
+
65
+ // Enable DWM rounded corners
66
+ EnableDwmRoundedCorners(hwnd);
67
  };
68
  }
69
 
70
+ /// <summary>
71
+ /// Enable native DWM rounded corners (Windows 11) and dark mode.
72
+ /// </summary>
73
+ private void EnableDwmRoundedCorners(IntPtr hwnd)
74
+ {
75
+ try
76
+ {
77
+ int cornerPref = Win32Api.DWMWCP_ROUND;
78
+ Win32Api.DwmSetWindowAttribute(hwnd, Win32Api.DWMWA_WINDOW_CORNER_PREFERENCE, ref cornerPref, Marshal.SizeOf(cornerPref));
79
+
80
+ int darkMode = 1;
81
+ Win32Api.DwmSetWindowAttribute(hwnd, Win32Api.DWMWA_USE_IMMERSIVE_DARK_MODE, ref darkMode, Marshal.SizeOf(darkMode));
82
+ }
83
+ catch { /* DWM not available on older Windows */ }
84
+ }
85
+
86
  private void Window_Loaded(object sender, RoutedEventArgs e)
87
  {
88
  if (_initialized) return;
 
329
  SearchBox.Focus();
330
  }
331
 
332
+ // -- Search (debounced, background thread) --
333
 
334
  private void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
335
  {
336
  var query = SearchBox.Text.Trim();
337
+
338
  if (string.IsNullOrEmpty(query))
339
  {
340
+ CancelPendingSearch();
341
  Dispatcher.Invoke(() =>
342
  {
343
  Results = new List<ResultItem>();
 
346
  return;
347
  }
348
 
349
+ CancelPendingSearch();
350
+
351
+ var cts = new CancellationTokenSource();
352
+ lock (_searchLock)
353
  {
354
+ _searchDebounceCts = cts;
355
  }
356
 
357
+ // Debounce: 25ms
358
+ Task.Run(async () =>
359
  {
360
+ try
361
+ {
362
+ await Task.Delay(25, cts.Token);
363
+ }
364
+ catch (TaskCanceledException)
365
+ {
366
+ return;
367
+ }
 
368
 
369
+ if (cts.IsCancellationRequested) return;
370
+
371
+ List<SearchResult> results;
372
+ lock (_indexLock)
373
+ {
374
+ results = SearchEngine.Search(_index, query, 50, _caseSensitive, _excludedDirs);
375
+ }
376
+
377
+ var items = results.Select((r, i) => new ResultItem
378
+ {
379
+ FullPath = r.FullPath,
380
+ DisplayName = Path.GetFileNameWithoutExtension(r.FullPath),
381
+ IsSelected = i == 0,
382
+ IsHovered = false,
383
+ Kind = r.Kind,
384
+ IconGlyph = GetIconGlyph(r.Kind),
385
+ BadgeLabel = GetBadgeLabel(r.Kind),
386
+ BadgeColor = GetBadgeColor(r.Kind)
387
+ }).ToList();
388
+
389
+ Dispatcher.Invoke(() =>
390
+ {
391
+ if (cts.IsCancellationRequested) return;
392
+ _selectedIndex = 0;
393
+ Results = items;
394
+ UpdateVisibility();
395
+ StatusText.Text = $"{items.Count} results";
396
+ });
397
  });
398
  }
399
 
400
+ private void CancelPendingSearch()
401
+ {
402
+ lock (_searchLock)
403
+ {
404
+ _searchDebounceCts?.Cancel();
405
+ _searchDebounceCts?.Dispose();
406
+ _searchDebounceCts = null;
407
+ }
408
+ }
409
+
410
  private void UpdateVisibility()
411
  {
412
  bool hasResults = Results.Count > 0;
 
512
  protected override void OnClosing(CancelEventArgs e)
513
  {
514
  _cts?.Cancel();
515
+ CancelPendingSearch();
516
  foreach (var w in _watchers) w.Dispose();
517
  _watchers.Clear();
518
  CacheManager.SaveCache(_index);