From b9a43147dc3d137e53de16938b6c0a5771b2a76d Mon Sep 17 00:00:00 2001 From: AWAS666 Date: Thu, 9 Oct 2025 12:35:04 +0200 Subject: [PATCH 1/5] enable reordering with drap and drop on websearches --- .../SettingsControl.xaml | 4 + .../SettingsControl.xaml.cs | 79 ++++++++++++++++++- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml index d1f48212b..152558e81 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml @@ -52,6 +52,10 @@ MouseDoubleClick="MouseDoubleClickItem" SelectedItem="{Binding Settings.SelectedSearchSource}" SizeChanged="ListView_SizeChanged" + PreviewMouseLeftButtonDown="ListView_PreviewMouseLeftButtonDown" + PreviewMouseMove="ListView_PreviewMouseMove" + AllowDrop="True" + Drop="ListView_Drop" Style="{StaticResource {x:Static GridView.GridViewStyleKey}}"> diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs index 55fe99824..d319e3158 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs @@ -1,7 +1,10 @@ -using System.Windows; -using System.Windows.Controls; +using System; using System.ComponentModel; +using System.Windows; +using System.Windows.Controls; using System.Windows.Data; +using System.Windows.Input; +using System.Windows.Media; namespace Flow.Launcher.Plugin.WebSearch { @@ -12,6 +15,7 @@ namespace Flow.Launcher.Plugin.WebSearch { private readonly Settings _settings; private readonly PluginInitContext _context; + private Point _dragStartPoint; public SettingsControl(PluginInitContext context, SettingsViewModel viewModel) { @@ -163,5 +167,76 @@ namespace Flow.Launcher.Plugin.WebSearch gView.Columns[3].Width = workingWidth * col4; gView.Columns[4].Width = workingWidth * col5; } + + private void ListView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + _dragStartPoint = e.GetPosition(null); + } + + private void ListView_PreviewMouseMove(object sender, MouseEventArgs e) + { + Point mousePos = e.GetPosition(null); + Vector diff = _dragStartPoint - mousePos; + + if (e.LeftButton == MouseButtonState.Pressed && + (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || + Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)) + { + ListView listView = sender as ListView; + ListViewItem listViewItem = FindAncestor((DependencyObject)e.OriginalSource); + + if (listViewItem == null) return; + + SearchSource item = (SearchSource)listView.ItemContainerGenerator.ItemFromContainer(listViewItem); + if (item == null) return; + + DragDrop.DoDragDrop(listViewItem, item, DragDropEffects.Move); + } + } + + private void ListView_Drop(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(typeof(SearchSource))) + { + SearchSource droppedData = e.Data.GetData(typeof(SearchSource)) as SearchSource; + ListView listView = sender as ListView; + var target = GetNearestContainer(e.OriginalSource); + + if (target == null) + return; + + SearchSource targetData = (SearchSource)listView.ItemContainerGenerator.ItemFromContainer(target); + + var items = _settings.SearchSources; + int removedIdx = items.IndexOf(droppedData); + int targetIdx = items.IndexOf(targetData); + + if (removedIdx == targetIdx) + return; + + items.RemoveAt(removedIdx); + items.Insert(targetIdx, droppedData); + } + } + + private ListViewItem GetNearestContainer(object source) + { + var element = source as UIElement; + while (element != null && !(element is ListViewItem)) + element = VisualTreeHelper.GetParent(element) as UIElement; + + return element as ListViewItem; + } + + private static T FindAncestor(DependencyObject current) where T : DependencyObject + { + while (current != null) + { + if (current is T) + return (T)current; + current = VisualTreeHelper.GetParent(current); + } + return null; + } } } From 87676d2994c470128edfaa1ea54cfd47357dafa4 Mon Sep 17 00:00:00 2001 From: AWAS666 Date: Fri, 10 Oct 2025 10:06:42 +0200 Subject: [PATCH 2/5] fix: error when dragging downwards --- Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs index d319e3158..5eadf2187 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs @@ -215,7 +215,7 @@ namespace Flow.Launcher.Plugin.WebSearch return; items.RemoveAt(removedIdx); - items.Insert(targetIdx, droppedData); + items.Insert(removedIdx < targetIdx ? targetIdx - 1 : targetIdx, droppedData); } } From 20a865f01219dae61750e874bfdb64b263b4fe1a Mon Sep 17 00:00:00 2001 From: AWAS666 Date: Fri, 10 Oct 2025 10:06:54 +0200 Subject: [PATCH 3/5] missing nullchecks and casts --- .../Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs index 5eadf2187..3399b1226 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs @@ -182,7 +182,7 @@ namespace Flow.Launcher.Plugin.WebSearch (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)) { - ListView listView = sender as ListView; + var listView = (ListView)sender; ListViewItem listViewItem = FindAncestor((DependencyObject)e.OriginalSource); if (listViewItem == null) return; @@ -199,7 +199,7 @@ namespace Flow.Launcher.Plugin.WebSearch if (e.Data.GetDataPresent(typeof(SearchSource))) { SearchSource droppedData = e.Data.GetData(typeof(SearchSource)) as SearchSource; - ListView listView = sender as ListView; + var listView = (ListView)sender; var target = GetNearestContainer(e.OriginalSource); if (target == null) @@ -207,6 +207,9 @@ namespace Flow.Launcher.Plugin.WebSearch SearchSource targetData = (SearchSource)listView.ItemContainerGenerator.ItemFromContainer(target); + if (targetData == null) + return; + var items = _settings.SearchSources; int removedIdx = items.IndexOf(droppedData); int targetIdx = items.IndexOf(targetData); From d7dd89d7198ddfc5f4ee7068dc705fcf8c7dc960 Mon Sep 17 00:00:00 2001 From: AWAS666 Date: Fri, 10 Oct 2025 11:40:06 +0200 Subject: [PATCH 4/5] change from remove/insert to move --- Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs index 3399b1226..6dc766fff 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs @@ -217,8 +217,7 @@ namespace Flow.Launcher.Plugin.WebSearch if (removedIdx == targetIdx) return; - items.RemoveAt(removedIdx); - items.Insert(removedIdx < targetIdx ? targetIdx - 1 : targetIdx, droppedData); + items.Move(removedIdx, targetIdx); } } From b297f3d3a3aaca7bcc1869aaee6d53206f8c08ed Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Sat, 11 Oct 2025 15:34:05 +0800 Subject: [PATCH 5/5] Fix ArgumentOutOfRangeException in WebSearch Plugin (#4041) --- .../ViewModels/SettingsPaneHotkeyViewModel.cs | 14 ++++++++++---- .../Languages/en.xaml | 1 + .../SearchSourceSetting.xaml.cs | 16 +++++++++++++--- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs index 3e7c3cb83..2ec69e81a 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneHotkeyViewModel.cs @@ -89,9 +89,12 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel if (window.ShowDialog() is not true) return; var index = Settings.CustomPluginHotkeys.IndexOf(settingItem); - Settings.CustomPluginHotkeys[index] = new CustomPluginHotkey(window.Hotkey, window.ActionKeyword); - HotKeyMapper.RemoveHotkey(settingItem.Hotkey); // remove origin hotkey - HotKeyMapper.SetCustomQueryHotkey(Settings.CustomPluginHotkeys[index]); // set new hotkey + if (index >= 0 && index < Settings.CustomPluginHotkeys.Count) + { + Settings.CustomPluginHotkeys[index] = new CustomPluginHotkey(window.Hotkey, window.ActionKeyword); + HotKeyMapper.RemoveHotkey(settingItem.Hotkey); // remove origin hotkey + HotKeyMapper.SetCustomQueryHotkey(Settings.CustomPluginHotkeys[index]); // set new hotkey + } } [RelayCommand] @@ -150,7 +153,10 @@ public partial class SettingsPaneHotkeyViewModel : BaseModel if (window.ShowDialog() is not true) return; var index = Settings.CustomShortcuts.IndexOf(settingItem); - Settings.CustomShortcuts[index] = new CustomShortcutModel(window.Key, window.Value); + if (index >= 0 && index < Settings.CustomShortcuts.Count) + { + Settings.CustomShortcuts[index] = new CustomShortcutModel(window.Key, window.Value); + } } [RelayCommand] diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/en.xaml index c6a74a047..5d65e4462 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Languages/en.xaml @@ -47,6 +47,7 @@ Please enter a URL Action keyword already exists, please enter a different one Success + Failed to update search source. The item may have been removed. Hint: You do not need to place custom images in this directory, if Flow's version is updated they will be lost. Flow will automatically copy any images outside of this directory across to WebSearch's custom image location. Web Searches diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs index acc2c1e5c..9508d61a0 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SearchSourceSetting.xaml.cs @@ -108,9 +108,19 @@ namespace Flow.Launcher.Plugin.WebSearch _context.API.AddActionKeyword(id, newKeyword); var index = _searchSources.IndexOf(_oldSearchSource); - _searchSources[index] = _searchSource; - - Close(); + + // Only update if we found the item in the collection + if (index >= 0 && index < _searchSources.Count) + { + _searchSources[index] = _searchSource; + Close(); + } + else + { + var warning = _api.GetTranslation("flowlauncher_plugin_websearch_edit_failed"); + _context.API.ShowMsgBox(warning); + Close(); + } } else {