How drawer search works
v0.9.7One box searches apps, contacts, calendar, the web, and does math. Results arrive in a fixed order, and fast sources never wait on slow ones.
- Settings → Drawer
One box, several sources
The drawer search box queries several sources at once and merges their results in one list. The sections appear in a fixed order: answer (math and unit conversion), apps, contacts, calendar, and web search.
Each source has its own settings switch. Calculator and web search are on by default. Contacts and calendar are off by default and require their respective permissions when you turn them on.
Fast sources never wait on slow ones
Apps, instant answers, and the web search row appear as you type. Contacts and calendar land a moment later. The drawer never holds app matches back waiting for them.
Under the hood
Every keystroke fires a new search. The search fans a query out to independent providers and merges them in one place in the fixed section order. Apps and instant answers post immediately. Contacts and calendar run content provider queries on a background thread behind a 200 ms debounce and a minimum query length. When a slow pass is scheduled, the fast pass posts as intermediate. The web search row also posts in the fast pass, but its suggestions arrive later — after a network round trip.
Why results don’t jump around
Contacts, calendar, and web suggestions keep showing the previous keystroke’s results until their own pass delivers, rather than emptying and refilling. This keeps rows from jumping up and back down, which would make a query typed at speed unreadable.
Only a section with a pass actually coming carries over rows. A source that is switched off or under its minimum query length has already given its real answer — empty — so stale rows would have nothing scheduled to clear them.
Under the hood
on new keystroke:
state = new query_state()
for section in sections:
if section will run a pass for this query:
state[section].rows = previous[section].rows # display only
# a section that is off, or under its length gate, starts empty —
# nothing is scheduled that would ever clear stale rows
# carried rows are not marked delivered, so "every source reported"
# still means what it says
Limits
Nothing you have searched before affects what a new query returns — there is no search history feeding into ranking, and no usage ranking outside contacts. Past searches are shown for re-running on the drawer’s home surface — see Drawer home. App matches are ordered by name score alone, never by launch frequency.