diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java index 978981906c1..4de9b5b682b 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java @@ -390,6 +390,45 @@ protected int getNumberOfFilteredResults() { return numberOfFilteredResults; } + /** + * Queries every provider that requires UI access in a single UI-thread pass and + * returns their sorted elements keyed by provider. Batching the queries avoids a + * blocking worker-to-UI round-trip per provider on each keystroke. + */ + private Map> computeUiProviderElements(String filter, String category, + IProgressMonitor monitor) { + List uiProviders = new ArrayList<>(); + for (QuickAccessProvider provider : providers) { + if (!provider.requiresUiAccess()) { + continue; + } + boolean isPreviousPickProvider = provider instanceof PreviousPicksProvider; + if (category != null && !category.equalsIgnoreCase(provider.getName()) && !isPreviousPickProvider) { + continue; + } + if (!filter.isEmpty() || isPreviousPickProvider || showAllMatches) { + uiProviders.add(provider); + } + } + if (uiProviders.isEmpty() || monitor.isCanceled() || table == null || table.isDisposed()) { + return Collections.emptyMap(); + } + Map> result = new HashMap<>(); + table.getDisplay().syncExec(() -> { + for (QuickAccessProvider provider : uiProviders) { + if (monitor.isCanceled()) { + return; + } + try { + result.put(provider, Arrays.asList(provider.getElementsSorted(filter, monitor))); + } catch (RuntimeException e) { + WorkbenchPlugin.log(e); + } + } + }); + return result; + } + /** * Returns a list per provider containing matching {@link QuickAccessEntry} that * should be displayed in the table given a text filter and a perfect match @@ -417,6 +456,11 @@ private List[] computeMatchingEntries(String filter, QuickAcce } final String finalFilter = filter; + // Query providers that must run on the UI thread once, in a single UI pass, + // rather than a separate blocking worker-to-UI round-trip per provider. + Map> uiProviderElements = computeUiProviderElements(finalFilter, + category, aMonitor); + // collect matching elements LinkedHashMap> elementsForProviders = new LinkedHashMap<>( providers.length); @@ -430,28 +474,12 @@ private List[] computeMatchingEntries(String filter, QuickAcce continue; } if (!filter.isEmpty() || isPreviousPickProvider || showAllMatches) { - AtomicReference> sortedElementRef = new AtomicReference<>(); + List sortedElements; if (provider.requiresUiAccess()) { - UIJob job = new UIJob( - NLS.bind(QuickAccessMessages.QuickAccessContents_processingProviderInUI, - provider.getName())) { - @Override - public IStatus runInUIThread(IProgressMonitor monitor) { - sortedElementRef.set(Arrays.asList(provider.getElementsSorted(finalFilter, monitor))); - return Status.OK_STATUS; - } - }; - job.setPriority(Job.INTERACTIVE); - job.schedule(); - try { - job.join(0, new NullProgressMonitor()); - } catch (Exception e) { - WorkbenchPlugin.log(e); - } + sortedElements = uiProviderElements.get(provider); } else { - sortedElementRef.set(Arrays.asList(provider.getElementsSorted(filter, aMonitor))); + sortedElements = Arrays.asList(provider.getElementsSorted(filter, aMonitor)); } - List sortedElements = sortedElementRef.get(); if (sortedElements == null) { sortedElements = Collections.emptyList(); } diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/QuickAccessMessages.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/QuickAccessMessages.java index 0281262417e..25d3904259d 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/QuickAccessMessages.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/QuickAccessMessages.java @@ -45,7 +45,6 @@ public class QuickAccessMessages extends NLS { public static String QuickAccessContents_activate; public static String QuickAccessContents_computeMatchingEntries_displayFeedback_jobName; public static String QuickaAcessContents_computeMatchingEntries; - public static String QuickAccessContents_processingProviderInUI; static { // initialize resource bundle diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/messages.properties b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/messages.properties index e6d2c86dd39..73add85c8c2 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/messages.properties +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/messages.properties @@ -35,4 +35,3 @@ QuickAccessContents_HelpCategory=Help QuickAccessContents_activate=Activate bundle for ''{0}'' proposals QuickAccessContents_computeMatchingEntries_displayFeedback_jobName=May show feedback when computing quick access QuickaAcessContents_computeMatchingEntries=\u23F3 Computing proposals for ''{0}'' -QuickAccessContents_processingProviderInUI=Processing ''{0}'' in UI Thread