Skip to content

Commit 9d551a5

Browse files
committed
Debounce Quick Access keystrokes before computing proposals
Every keystroke scheduled the background compute job immediately and cancelled the in-flight one, so fast typing triggered a compute per character even though only the final filter matters. Collapse a burst of keystrokes into a single computation: the modify listener now schedules the compute job with a 100 ms delay, and each new keystroke cancels the still-sleeping job from the previous one, so only the last keystroke in the window actually computes. The other callers (initial open, show-all toggle, resize) keep zero delay. The job is scheduled for the whole delay, so it stays visible to COMPUTE_JOB_FAMILY and tests that join that family still observe the pending compute.
1 parent 74e6073 commit 9d551a5

1 file changed

Lines changed: 21 additions & 3 deletions

File tree

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ public abstract class QuickAccessContents {
105105
/** Trailing-edge debounce window collapsing a burst of shell resizes. */
106106
private static final int RESIZE_DEBOUNCE_MS = 100;
107107

108+
/** Trailing-edge debounce window collapsing a burst of keystrokes. */
109+
private static final int FILTER_DEBOUNCE_MS = 100;
110+
108111
/**
109112
* Family of the background job that computes the matching entries. Lets tests
110113
* join on the streaming compute deterministically instead of polling the table.
@@ -165,6 +168,18 @@ private int computeNumberOfItems() {
165168
* @param filterInput The filter text to apply to results
166169
*/
167170
public void updateProposals(String filterInput) {
171+
updateProposals(filterInput, 0);
172+
}
173+
174+
/**
175+
* Recomputes the proposals, scheduling the background compute job after
176+
* {@code scheduleDelay} milliseconds. A non-zero delay lets a burst of keystrokes
177+
* collapse into a single computation: each keystroke cancels the still-sleeping job
178+
* from the previous one, so only the last keystroke in the window actually computes.
179+
* The job is scheduled (and therefore visible to {@link #COMPUTE_JOB_FAMILY}) for the
180+
* whole delay, so callers waiting on that family still observe the pending compute.
181+
*/
182+
private void updateProposals(String filterInput, int scheduleDelay) {
168183
// Lower-case once so all callers share one filter string; the matcher and
169184
// previous-pick lookup also require a lower-cased filter.
170185
final String filter = filterInput == null ? "" : filterInput.toLowerCase(); //$NON-NLS-1$
@@ -264,8 +279,10 @@ public void done(IJobChangeEvent event) {
264279
if (Policy.DEBUG_QUICK_ACCESS) {
265280
trace("Set last proposals Job: " + computeProposalsJob); //$NON-NLS-1$
266281
}
267-
currentComputeEntriesJob.schedule();
268-
computingFeedbackJob.schedule(200); // delay a bit so if proposals compute fast enough, we don't show feedback
282+
currentComputeEntriesJob.schedule(scheduleDelay);
283+
// Keep the feedback delay relative to when the compute actually starts, so the
284+
// debounce window never flashes the "computing" hint.
285+
computingFeedbackJob.schedule(scheduleDelay + 200);
269286
}
270287

271288
/**
@@ -741,7 +758,8 @@ public void keyReleased(KeyEvent e) {
741758
if (Policy.DEBUG_QUICK_ACCESS) {
742759
trace("Modify listener triggering proposals update"); //$NON-NLS-1$
743760
}
744-
updateProposals(text);
761+
// Coalesce a burst of keystrokes into a single computation.
762+
updateProposals(text, FILTER_DEBOUNCE_MS);
745763
});
746764
}
747765

0 commit comments

Comments
 (0)