Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Flow.Launcher/Converters/OpenResultHotkeyVisibilityConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ public object Convert(object value, Type targetType, object parameter, CultureIn

if (value is ListBoxItem listBoxItem
&& ItemsControl.ItemsControlFromItemContainer(listBoxItem) is ListBox listBox)
number = listBox.ItemContainerGenerator.IndexFromContainer(listBoxItem) + 1;
{
var dataItem = listBoxItem.DataContext;
if (dataItem != null)
{
var index = listBox.Items.IndexOf(dataItem);
if (index >= 0)
{
number = index + 1;
}
}
}

return number <= MaxVisibleHotkeys ? Visibility.Visible : Visibility.Collapsed;
}
Expand Down
17 changes: 14 additions & 3 deletions Flow.Launcher/Converters/OrdinalConverter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Globalization;
using System.Windows.Controls;
using System.Windows.Data;
Expand All @@ -15,9 +15,20 @@ public object Convert(object value, Type targetType, object parameter, CultureIn
return 0;
}

var res = listBox.ItemContainerGenerator.IndexFromContainer(listBoxItem) + 1;
return res == 10 ? 0 : res; // 10th item => HOTKEY+0
var dataItem = listBoxItem.DataContext;
if (dataItem == null)
{
return 0;
}

var index = listBox.Items.IndexOf(dataItem);
if (index < 0)
{
return 0;
}

var res = index + 1;
return res == 10 ? 0 : res; // 10th item => HOTKEY+0
}
Comment on lines +24 to 32
Copy link

@cubic-dev-ai cubic-dev-ai bot Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: listBox.Items.IndexOf(dataItem) performs a linear search (O(N)), which can cause performance degradation when the list is large (e.g., with "Everything" plugin or many results). This negates the performance benefits of using VirtualizationMode.Recycling.

Since the hotkey is typically only displayed for the first 10 items (and hidden otherwise by OpenResultHotkeyVisibilityConverter), you should optimize this by searching only the first 10 items. This changes the complexity from O(N) to O(1).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Flow.Launcher/Converters/OrdinalConverter.cs, line 24:

<comment>`listBox.Items.IndexOf(dataItem)` performs a linear search (O(N)), which can cause performance degradation when the list is large (e.g., with "Everything" plugin or many results). This negates the performance benefits of using `VirtualizationMode.Recycling`.

Since the hotkey is typically only displayed for the first 10 items (and hidden otherwise by `OpenResultHotkeyVisibilityConverter`), you should optimize this by searching only the first 10 items. This changes the complexity from O(N) to O(1).</comment>

<file context>
@@ -15,9 +15,20 @@ public object Convert(object value, Type targetType, object parameter, CultureIn
+            return 0;
+        }
 
+        var index = listBox.Items.IndexOf(dataItem);
+        if (index < 0)
+        {
</file context>
Suggested change
var index = listBox.Items.IndexOf(dataItem);
if (index < 0)
{
return 0;
}
var res = index + 1;
return res == 10 ? 0 : res; // 10th item => HOTKEY+0
}
var items = listBox.Items;
for (int i = 0; i < items.Count && i < 10; i++)
{
if (Equals(items[i], dataItem))
{
var res = i + 1;
return res == 10 ? 0 : res;
}
}
return 0;
Fix with Cubic


public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new InvalidOperationException();
Expand Down
4 changes: 2 additions & 2 deletions Flow.Launcher/ResultListBox.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
Style="{DynamicResource BaseListboxStyle}"
VirtualizingPanel.ScrollUnit="Item"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard"
VirtualizingStackPanel.VirtualizationMode="Recycling"
Visibility="{Binding Visibility}"
mc:Ignorable="d">
<!-- IsSynchronizedWithCurrentItem: http://stackoverflow.com/a/7833798/2833083 -->
Expand Down Expand Up @@ -82,7 +82,7 @@
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}+{1}">
<Binding Mode="OneWay" Path="Settings.OpenResultModifiers" />
<Binding Converter="{StaticResource ResourceKey=OrdinalConverter}" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}" />
<Binding Converter="{StaticResource ResourceKey=OrdinalConverter}" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Expand Down Expand Up @@ -164,7 +164,7 @@
<RowDefinition x:Name="SubTitleRowDefinition" Height="Auto" />
</Grid.RowDefinitions>
<ProgressBar
x:Name="progressbarResult"

Check warning on line 167 in Flow.Launcher/ResultListBox.xaml

View workflow job for this annotation

GitHub Actions / Check Spelling

`progressbar` is not a recognized word. (unrecognized-spelling)
Grid.Row="0"
Foreground="{Binding Result.ProgressBarColor}"
Value="{Binding ResultProgress, Mode=OneWay}">
Expand Down
15 changes: 9 additions & 6 deletions Flow.Launcher/ResultListBox.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
public partial class ResultListBox
{
protected Lock _lock = new();
private Point _lastpos;

Check warning on line 14 in Flow.Launcher/ResultListBox.xaml.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`lastpos` is not a recognized word. (unrecognized-spelling)
private ListBoxItem curItem = null;
private ResultViewModel _currentResult = null;
public ResultListBox()
{
InitializeComponent();
Expand Down Expand Up @@ -60,9 +60,12 @@
{
lock (_lock)
{
curItem = (ListBoxItem)sender;
var p = e.GetPosition((IInputElement)sender);
_lastpos = p;
if (sender is FrameworkElement { DataContext: ResultViewModel result })
{
_currentResult = result;
var p = e.GetPosition((IInputElement)sender);
_lastpos = p;

Check warning on line 67 in Flow.Launcher/ResultListBox.xaml.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`lastpos` is not a recognized word. (unrecognized-spelling)

Check warning on line 67 in Flow.Launcher/ResultListBox.xaml.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`lastpos` is not a recognized word. (unrecognized-spelling)
}
}
}

Expand All @@ -71,7 +74,7 @@
lock (_lock)
{
var p = e.GetPosition((IInputElement)sender);
if (_lastpos != p)

Check warning on line 77 in Flow.Launcher/ResultListBox.xaml.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`lastpos` is not a recognized word. (unrecognized-spelling)

Check warning on line 77 in Flow.Launcher/ResultListBox.xaml.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`lastpos` is not a recognized word. (unrecognized-spelling)
{
((ListBoxItem)sender).IsSelected = true;
}
Expand All @@ -82,9 +85,9 @@
{
lock (_lock)
{
if (curItem != null)
if (_currentResult != null && sender is ListBox listBox)
{
curItem.IsSelected = true;
listBox.SelectedItem = _currentResult;
}
}
}
Expand Down
Loading