From 9c1ffae14008ce388b9d9b7db809c145673d9396 Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Fri, 10 Apr 2026 19:50:40 +0300 Subject: [PATCH] fix(ui): add keyboard navigation to character selection screen Add Up/Down arrow keys to cycle through character list and Enter to select. Claim arrow key ownership via SetKeyOwner to prevent ImGui nav from moving focus to other widgets. Lock Enter key until release to prevent the keypress from activating chat on the game screen. Signed-off-by: Pavel Okhlopkov --- src/ui/character_screen.cpp | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/ui/character_screen.cpp b/src/ui/character_screen.cpp index 8024ee5e..67c758b7 100644 --- a/src/ui/character_screen.cpp +++ b/src/ui/character_screen.cpp @@ -6,6 +6,7 @@ #include "core/application.hpp" #include "core/logger.hpp" #include +#include #include #include #include @@ -241,6 +242,43 @@ void CharacterScreen::render(game::GameHandler& gameHandler) { ImGui::EndTable(); } + + // Keyboard navigation: Up/Down to change selection, Enter to enter world + // Claim ownership of arrow keys so ImGui nav doesn't move focus between buttons + ImGuiID charListOwner = ImGui::GetID("CharListNav"); + ImGui::SetKeyOwner(ImGuiKey_UpArrow, charListOwner); + ImGui::SetKeyOwner(ImGuiKey_DownArrow, charListOwner); + + if (!characters.empty() && deleteConfirmStage == 0) { + if (ImGui::IsKeyPressed(ImGuiKey_UpArrow)) { + if (selectedCharacterIndex > 0) { + selectedCharacterIndex--; + selectedCharacterGuid = characters[selectedCharacterIndex].guid; + saveLastCharacter(selectedCharacterGuid); + } + } + if (ImGui::IsKeyPressed(ImGuiKey_DownArrow)) { + if (selectedCharacterIndex < static_cast(characters.size()) - 1) { + selectedCharacterIndex++; + selectedCharacterGuid = characters[selectedCharacterIndex].guid; + saveLastCharacter(selectedCharacterGuid); + } + } + if (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter)) { + if (selectedCharacterIndex >= 0 && + selectedCharacterIndex < static_cast(characters.size())) { + const auto& ch = characters[selectedCharacterIndex]; + characterSelected = true; + saveLastCharacter(ch.guid); + // Claim Enter so the game screen doesn't activate chat on the same press + ImGui::SetKeyOwner(ImGuiKey_Enter, charListOwner, ImGuiInputFlags_LockUntilRelease); + ImGui::SetKeyOwner(ImGuiKey_KeypadEnter, charListOwner, ImGuiInputFlags_LockUntilRelease); + gameHandler.selectCharacter(ch.guid); + if (onCharacterSelected) onCharacterSelected(ch.guid); + } + } + } + ImGui::EndChild(); // ── Right: Details panel ──