Private
Public Access
0
0

fix(palette): set keyboard focus correctly + support click-to-execute

- set_keyboard_focus_here() now called BEFORE input_text (was after, so focus went to wrong widget)
- Only call set_keyboard_focus_here ONCE per open (via _command_palette_focused flag) so focus isn't stolen on subsequent frames
- Added imgui.Cond_.always to window pos/size so it stays centered on re-render
- Click on a result now immediately executes the command (was: only on Enter key, which wasn't reaching the modal)
- Reset _command_palette_focused on close so next open gets focus again
This commit is contained in:
2026-06-02 22:22:00 -04:00
parent 19c7a6e449
commit 592f816caf
+22 -14
View File
@@ -111,27 +111,37 @@ def render_palette_modal(app: Any, commands: List[Command]) -> None:
viewport = imgui.get_main_viewport() viewport = imgui.get_main_viewport()
center = viewport.get_center() center = viewport.get_center()
imgui.set_next_window_pos((center.x - 300, center.y - 200)) imgui.set_next_window_pos((center.x - 300, center.y - 200), imgui.Cond_.always)
imgui.set_next_window_size((600, 400)) imgui.set_next_window_size((600, 400), imgui.Cond_.always)
if not hasattr(app, "_command_palette_query"): if not hasattr(app, "_command_palette_query"):
app._command_palette_query = "" app._command_palette_query = ""
if not hasattr(app, "_command_palette_selected"): if not hasattr(app, "_command_palette_selected"):
app._command_palette_selected = 0 app._command_palette_selected = 0
if not hasattr(app, "_command_palette_focused"):
app._command_palette_focused = False
# Set focus on the input field ONCE per open.
# set_keyboard_focus_here must be called BEFORE the widget to give it focus.
if not app._command_palette_focused:
imgui.set_keyboard_focus_here()
app._command_palette_focused = True
# Escape closes the palette.
if imgui.is_key_pressed(imgui.Key.escape): if imgui.is_key_pressed(imgui.Key.escape):
app.show_command_palette = False app.show_command_palette = False
app._command_palette_focused = False
return return
expanded, _ = imgui.begin("Command Palette##manual_slop") expanded, opened = imgui.begin("Command Palette##manual_slop", True, imgui.WindowFlags_.no_collapse)
if not expanded: if not expanded or not opened:
app.show_command_palette = False app.show_command_palette = False
app._command_palette_focused = False
imgui.end() imgui.end()
return return
imgui.set_next_item_width(-1) imgui.set_next_item_width(-1)
changed, app._command_palette_query = imgui.input_text("##query", app._command_palette_query, 256) _, app._command_palette_query = imgui.input_text("##query", app._command_palette_query)
imgui.set_keyboard_focus_here()
results = fuzzy_match(app._command_palette_query, commands, top_n=20) results = fuzzy_match(app._command_palette_query, commands, top_n=20)
@@ -142,14 +152,12 @@ def render_palette_modal(app: Any, commands: List[Command]) -> None:
clicked, _ = imgui.selectable(label, is_selected) clicked, _ = imgui.selectable(label, is_selected)
if clicked: if clicked:
app._command_palette_selected = i app._command_palette_selected = i
if is_selected: if scored.command.action:
imgui.set_item_default_focus() scored.command.action(app)
if imgui.is_key_pressed(imgui.Key.enter) or imgui.is_key_pressed(imgui.Key.keypad_enter): app.show_command_palette = False
if scored.command.action: app._command_palette_query = ""
scored.command.action(app) app._command_palette_selected = 0
app.show_command_palette = False app._command_palette_focused = False
app._command_palette_query = ""
app._command_palette_selected = 0
if not results: if not results:
imgui.text_disabled("No matching commands.") imgui.text_disabled("No matching commands.")
imgui.end_child() imgui.end_child()