From 592f816caf89e9f63360abeb4030fe4ca5ee67dc Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 2 Jun 2026 22:22:00 -0400 Subject: [PATCH] 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 --- src/command_palette.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/command_palette.py b/src/command_palette.py index 73c364da..4be5a74b 100644 --- a/src/command_palette.py +++ b/src/command_palette.py @@ -111,27 +111,37 @@ def render_palette_modal(app: Any, commands: List[Command]) -> None: viewport = imgui.get_main_viewport() center = viewport.get_center() - imgui.set_next_window_pos((center.x - 300, center.y - 200)) - imgui.set_next_window_size((600, 400)) + imgui.set_next_window_pos((center.x - 300, center.y - 200), imgui.Cond_.always) + imgui.set_next_window_size((600, 400), imgui.Cond_.always) if not hasattr(app, "_command_palette_query"): app._command_palette_query = "" if not hasattr(app, "_command_palette_selected"): 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): app.show_command_palette = False + app._command_palette_focused = False return - expanded, _ = imgui.begin("Command Palette##manual_slop") - if not expanded: + expanded, opened = imgui.begin("Command Palette##manual_slop", True, imgui.WindowFlags_.no_collapse) + if not expanded or not opened: app.show_command_palette = False + app._command_palette_focused = False imgui.end() return imgui.set_next_item_width(-1) - changed, app._command_palette_query = imgui.input_text("##query", app._command_palette_query, 256) - imgui.set_keyboard_focus_here() + _, app._command_palette_query = imgui.input_text("##query", app._command_palette_query) 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) if clicked: app._command_palette_selected = i - if is_selected: - imgui.set_item_default_focus() - if imgui.is_key_pressed(imgui.Key.enter) or imgui.is_key_pressed(imgui.Key.keypad_enter): - if scored.command.action: - scored.command.action(app) - app.show_command_palette = False - app._command_palette_query = "" - app._command_palette_selected = 0 + if scored.command.action: + scored.command.action(app) + app.show_command_palette = False + app._command_palette_query = "" + app._command_palette_selected = 0 + app._command_palette_focused = False if not results: imgui.text_disabled("No matching commands.") imgui.end_child()