@@ -71,6 +71,7 @@ bool editor::SceneWindow::isFocused() const {
7171}
7272
7373void editor::SceneWindow::resetProjectState () {
74+ releasePlayKeys (0 );
7475 windowFocused = false ;
7576 mouseLeftDown = false ;
7677 mouseLeftDraggedInside = false ;
@@ -84,6 +85,9 @@ void editor::SceneWindow::resetProjectState() {
8485}
8586
8687void editor::SceneWindow::clearSceneState (uint32_t sceneId) {
88+ if (sceneId == playKeysSceneId) {
89+ releasePlayKeys (0 );
90+ }
8791 draggingMouse.erase (sceneId);
8892 suppressLeftMouseUntilRelease.erase (sceneId);
8993 walkSpeed.erase (sceneId);
@@ -539,17 +543,20 @@ void editor::SceneWindow::forwardPlayKeyboardInput(ImGuiIO& io, int mods){
539543 Engine::systemCharInput (charInput);
540544 }
541545 Engine::systemKeyDown (engineKey, false , mods);
546+ playPressedKeys.insert (engineKey);
542547 }else if (allowRepeat && ImGui::IsKeyPressed (imguiKey, true )){
543548 if (charInput != 0 ){
544549 Engine::systemCharInput (charInput);
545550 }
546551 Engine::systemKeyDown (engineKey, true , mods);
552+ playPressedKeys.insert (engineKey);
547553 }
548554 };
549555
550556 auto forwardKeyRelease = [&](ImGuiKey imguiKey, int engineKey){
551557 if (ImGui::IsKeyReleased (imguiKey)){
552558 Engine::systemKeyUp (engineKey, false , mods);
559+ playPressedKeys.erase (engineKey);
553560 }
554561 };
555562
@@ -558,29 +565,75 @@ void editor::SceneWindow::forwardPlayKeyboardInput(ImGuiIO& io, int mods){
558565 forwardKeyRelease (imguiKey, engineKey);
559566 };
560567
568+ auto forwardKeyRange = [&](ImGuiKey imguiFirst, int engineFirst, int count){
569+ for (int i = 0 ; i < count; i++){
570+ forwardKey (static_cast <ImGuiKey>(static_cast <int >(imguiFirst) + i), engineFirst + i);
571+ }
572+ };
573+
561574 forwardKey (ImGuiKey_Tab, D_KEY_TAB , L' \t ' , false );
562575 forwardKey (ImGuiKey_Backspace, D_KEY_BACKSPACE , L' \b ' );
563576 forwardKey (ImGuiKey_Enter, D_KEY_ENTER , L' \r ' , false );
564- forwardKey (ImGuiKey_KeypadEnter, D_KEY_ENTER , L' \r ' , false );
577+ forwardKey (ImGuiKey_KeypadEnter, D_KEY_KP_ENTER , L' \r ' , false );
565578 forwardKey (ImGuiKey_Escape, D_KEY_ESCAPE , L' \e ' , false );
566579 forwardKey (ImGuiKey_Space, D_KEY_SPACE );
567580 forwardKey (ImGuiKey_LeftArrow, D_KEY_LEFT );
568581 forwardKey (ImGuiKey_RightArrow, D_KEY_RIGHT );
569582 forwardKey (ImGuiKey_UpArrow, D_KEY_UP );
570583 forwardKey (ImGuiKey_DownArrow, D_KEY_DOWN );
584+ forwardKey (ImGuiKey_Insert, D_KEY_INSERT , 0 , false );
571585 forwardKey (ImGuiKey_Home, D_KEY_HOME , 0 , false );
572586 forwardKey (ImGuiKey_End, D_KEY_END , 0 , false );
587+ forwardKey (ImGuiKey_PageUp, D_KEY_PAGE_UP );
588+ forwardKey (ImGuiKey_PageDown, D_KEY_PAGE_DOWN );
573589 forwardKey (ImGuiKey_Delete, D_KEY_DELETE );
574590
575- for (int i = 0 ; i < 10 ; i++){
576- ImGuiKey imguiKey = static_cast <ImGuiKey>(static_cast <int >(ImGuiKey_0) + i);
577- forwardKey (imguiKey, D_KEY_0 + i);
578- }
591+ forwardKey (ImGuiKey_Apostrophe, D_KEY_APOSTROPHE );
592+ forwardKey (ImGuiKey_Comma, D_KEY_COMMA );
593+ forwardKey (ImGuiKey_Minus, D_KEY_MINUS );
594+ forwardKey (ImGuiKey_Period, D_KEY_PERIOD );
595+ forwardKey (ImGuiKey_Slash, D_KEY_SLASH );
596+ forwardKey (ImGuiKey_Semicolon, D_KEY_SEMICOLON );
597+ forwardKey (ImGuiKey_Equal, D_KEY_EQUAL );
598+ forwardKey (ImGuiKey_LeftBracket, D_KEY_LEFT_BRACKET );
599+ forwardKey (ImGuiKey_Backslash, D_KEY_BACKSLASH );
600+ forwardKey (ImGuiKey_RightBracket, D_KEY_RIGHT_BRACKET );
601+ forwardKey (ImGuiKey_GraveAccent, D_KEY_GRAVE_ACCENT );
602+
603+ forwardKey (ImGuiKey_CapsLock, D_KEY_CAPS_LOCK , 0 , false );
604+ forwardKey (ImGuiKey_ScrollLock, D_KEY_SCROLL_LOCK , 0 , false );
605+ forwardKey (ImGuiKey_NumLock, D_KEY_NUM_LOCK , 0 , false );
606+ forwardKey (ImGuiKey_PrintScreen, D_KEY_PRINT_SCREEN , 0 , false );
607+ forwardKey (ImGuiKey_Pause, D_KEY_PAUSE , 0 , false );
608+
609+ forwardKey (ImGuiKey_LeftShift, D_KEY_LEFT_SHIFT , 0 , false );
610+ forwardKey (ImGuiKey_LeftCtrl, D_KEY_LEFT_CONTROL , 0 , false );
611+ forwardKey (ImGuiKey_LeftAlt, D_KEY_LEFT_ALT , 0 , false );
612+ forwardKey (ImGuiKey_LeftSuper, D_KEY_LEFT_SUPER , 0 , false );
613+ forwardKey (ImGuiKey_RightShift, D_KEY_RIGHT_SHIFT , 0 , false );
614+ forwardKey (ImGuiKey_RightCtrl, D_KEY_RIGHT_CONTROL , 0 , false );
615+ forwardKey (ImGuiKey_RightAlt, D_KEY_RIGHT_ALT , 0 , false );
616+ forwardKey (ImGuiKey_RightSuper, D_KEY_RIGHT_SUPER , 0 , false );
617+ forwardKey (ImGuiKey_Menu, D_KEY_MENU , 0 , false );
618+
619+ forwardKeyRange (ImGuiKey_0, D_KEY_0 , 10 );
620+ forwardKeyRange (ImGuiKey_A, D_KEY_A , 26 );
621+ forwardKeyRange (ImGuiKey_F1, D_KEY_F1 , 24 );
622+ forwardKeyRange (ImGuiKey_Keypad0, D_KEY_KP_0 , 10 );
623+
624+ forwardKey (ImGuiKey_KeypadDecimal, D_KEY_KP_DECIMAL );
625+ forwardKey (ImGuiKey_KeypadDivide, D_KEY_KP_DIVIDE );
626+ forwardKey (ImGuiKey_KeypadMultiply, D_KEY_KP_MULTIPLY );
627+ forwardKey (ImGuiKey_KeypadSubtract, D_KEY_KP_SUBTRACT );
628+ forwardKey (ImGuiKey_KeypadAdd, D_KEY_KP_ADD );
629+ forwardKey (ImGuiKey_KeypadEqual, D_KEY_KP_EQUAL );
630+ }
579631
580- for (int i = 0 ; i < 26 ; i++ ){
581- ImGuiKey imguiKey = static_cast <ImGuiKey>( static_cast < int >(ImGuiKey_A) + i);
582- forwardKey (imguiKey, D_KEY_A + i );
632+ void editor::SceneWindow::releasePlayKeys (int mods ){
633+ for ( int key : playPressedKeys){
634+ Engine::systemKeyUp (key, false , mods );
583635 }
636+ playPressedKeys.clear ();
584637}
585638
586639void editor::SceneWindow::sceneEventHandler (SceneProject* sceneProject) {
@@ -600,34 +653,50 @@ void editor::SceneWindow::sceneEventHandler(SceneProject* sceneProject) {
600653 bool isMouseInWindow = ImGui::IsWindowHovered () && (mousePos.x >= windowPos.x && mousePos.x <= windowPos.x + windowSize.x &&
601654 mousePos.y >= windowPos.y && mousePos.y <= windowPos.y + windowSize.y );
602655
603- // When scene is playing, forward mouse events to Engine
604- if (sceneProject->playState == ScenePlayState::PLAYING && isMouseInWindow) {
605- float x = mousePos.x - windowPos.x ;
606- float y = mousePos.y - windowPos.y ;
656+ int mods = 0 ;
657+ if (io.KeyShift ) mods |= D_MODIFIER_SHIFT ;
658+ if (io.KeyCtrl ) mods |= D_MODIFIER_CONTROL ;
659+ if (io.KeyAlt ) mods |= D_MODIFIER_ALT ;
660+ if (io.KeySuper ) mods |= D_MODIFIER_SUPER ;
607661
608- int mods = 0 ;
609- if (io. KeyShift ) mods |= D_MODIFIER_SHIFT ;
610- if (io. KeyCtrl ) mods |= D_MODIFIER_CONTROL ;
611- if (io. KeyAlt ) mods |= D_MODIFIER_ALT ;
612- if (io. KeySuper ) mods |= D_MODIFIER_SUPER ;
662+ // When scene is playing, forward mouse and keyboard events to Engine
663+ if (sceneProject-> playState == ScenePlayState:: PLAYING ) {
664+ if (isMouseInWindow) {
665+ float x = mousePos. x - windowPos. x ;
666+ float y = mousePos. y - windowPos. y ;
613667
614- Engine::systemMouseMove (x, y, mods);
668+ Engine::systemMouseMove (x, y, mods);
615669
616- if (mouseWheel != 0 ) {
617- Engine::systemMouseScroll (0 , mouseWheel, mods);
618- }
619-
620- for (int i = 0 ; i < 5 ; i++) {
621- if (ImGui::IsMouseClicked (i)) {
622- Engine::systemMouseDown (i, x, y, mods);
670+ if (mouseWheel != 0 ) {
671+ Engine::systemMouseScroll (0 , mouseWheel, mods);
623672 }
624- if (ImGui::IsMouseReleased (i)) {
625- Engine::systemMouseUp (i, x, y, mods);
673+
674+ for (int i = 0 ; i < 5 ; i++) {
675+ if (ImGui::IsMouseClicked (i)) {
676+ Engine::systemMouseDown (i, x, y, mods);
677+ }
678+ if (ImGui::IsMouseReleased (i)) {
679+ Engine::systemMouseUp (i, x, y, mods);
680+ }
626681 }
627682 }
628683
629- forwardPlayKeyboardInput (io, mods);
630- return ;
684+ // Keyboard follows window focus, not mouse hover, so held keys keep
685+ // working while the mouse drifts out of the window. On focus loss the
686+ // key-up events would never arrive, so release held keys explicitly.
687+ if (ImGui::IsWindowFocused (ImGuiFocusedFlags_ChildWindows)) {
688+ playKeysSceneId = sceneProject->id ;
689+ forwardPlayKeyboardInput (io, mods);
690+ } else if (playKeysSceneId == sceneProject->id ) {
691+ releasePlayKeys (mods);
692+ }
693+
694+ if (isMouseInWindow) {
695+ return ;
696+ }
697+ } else if (playKeysSceneId == sceneProject->id ) {
698+ // Play stopped or paused with keys still held
699+ releasePlayKeys (mods);
631700 }
632701
633702 size_t sceneId = sceneProject->id ;
0 commit comments