Repository navigation
Closed
Labels
P3Low priority / Polish & EnhancementsLow priority / Polish & EnhancementsfrontendTheme parser epic label: frontendTheme parser epic label: frontendperformanceTheme parser epic label: performanceTheme parser epic label: performanceuiUser interface components and widgetsUser interface components and widgetsuxUser experience, keyboard shortcuts and interactionsUser experience, keyboard shortcuts and interactions
Description
Problem
In lib/features/command_palette/command_palette_dialog.dart and quick_switcher_dialog.dart:
- Double
setStateon mouse movement:
InListView.builder, each item defines:
onHover: (_) => setState(() => _selected = index),In Flutter, InkWell.onHover fires with true on pointer enter and false on pointer exit. When moving the cursor between list rows, this triggers two consecutive setState calls (one for unhovering the old item, one for hovering the new item), rebuilding the entire dialog twice per item boundary without checking if (isHovered).
- Repeated
search()evaluation:
InCommandPaletteDialog,_hitsis a computed getter:
List<QueryaCommand> get _hits {
if (_objectPrefix) return const [];
final ctx = widget.hostContext.mounted ? widget.hostContext : context;
return QueryaCommandRegistry.instance.search(_controller.text, context: ctx);
}It is called in _move(), in arrow navigation, and twice during build(). Because each mouse hover rebuilds the dialog, search() and string matching execute repeatedly on every pointer pixel movement.
Code Locations
lib/features/command_palette/command_palette_dialog.dart(lines 62–66, 161)lib/features/command_palette/quick_switcher_dialog.dart(line 230)
UI Kit Relationship
- Feature Component (Not UI Kit): These dialogs live in
lib/features/command_palette/. They use the UI Kit modal shell (showAppDialog/QueryaDialogCard), but the list rows are implemented ad-hoc using rawmaterial.InkWellandDecoratedBox. - No open issues currently track this hover/search overhead.
Proposed Solution
- Guard hover state updates so only positive enters update selection:
onHover: (hovered) {
if (hovered && _selected != index) {
setState(() => _selected = index);
}
}- Cache search results (
_hits) on query change instead of re-evaluating the getter insidebuild(). - Consider using a localized
ValueNotifier<int>for selection or item-level hover widgets so the parent dialog and search input do not rebuild on hover.
Acceptance Criteria
- Pointer hovering over commands in Command Palette / Quick Switcher does not trigger redundant full dialog rebuilds.
-
QueryaCommandRegistry.instance.searchis called only when the search query text changes or new commands are registered.
Metadata
Metadata
Assignees
Labels
P3Low priority / Polish & EnhancementsLow priority / Polish & EnhancementsfrontendTheme parser epic label: frontendTheme parser epic label: frontendperformanceTheme parser epic label: performanceTheme parser epic label: performanceuiUser interface components and widgetsUser interface components and widgetsuxUser experience, keyboard shortcuts and interactionsUser experience, keyboard shortcuts and interactions
Activity
ZhuchkaTriplesix commentedon Oct 11, 2026
Done in #1426.