diff --git a/core/debugger/debugger_marshalls.cpp b/core/debugger/debugger_marshalls.cpp index f4283e0ea9c..cc36ca4816a 100644 --- a/core/debugger/debugger_marshalls.cpp +++ b/core/debugger/debugger_marshalls.cpp @@ -147,3 +147,37 @@ bool DebuggerMarshalls::OutputError::deserialize(const Array &p_arr) { CHECK_END(p_arr, idx, "OutputError"); return true; } + +Array DebuggerMarshalls::serialize_key_shortcut(const Ref &p_shortcut) { + ERR_FAIL_COND_V(p_shortcut.is_null(), Array()); + Array keys; + for (const Ref ev : p_shortcut->get_events()) { + const Ref kev = ev; + ERR_CONTINUE(kev.is_null()); + if (kev->get_physical_keycode() != Key::NONE) { + keys.push_back(true); + keys.push_back(kev->get_physical_keycode_with_modifiers()); + } else { + keys.push_back(false); + keys.push_back(kev->get_keycode_with_modifiers()); + } + } + return keys; +} + +Ref DebuggerMarshalls::deserialize_key_shortcut(const Array &p_keys) { + Array key_events; + ERR_FAIL_COND_V(p_keys.size() % 2 != 0, Ref()); + for (int i = 0; i < p_keys.size(); i += 2) { + ERR_CONTINUE(p_keys[i].get_type() != Variant::BOOL); + ERR_CONTINUE(p_keys[i + 1].get_type() != Variant::INT); + key_events.push_back(InputEventKey::create_reference((Key)p_keys[i + 1].operator int(), p_keys[i].operator bool())); + } + if (key_events.is_empty()) { + return Ref(); + } + Ref shortcut; + shortcut.instantiate(); + shortcut->set_events(key_events); + return shortcut; +} diff --git a/core/debugger/debugger_marshalls.h b/core/debugger/debugger_marshalls.h index 1b81623688e..1072ddaeb7f 100644 --- a/core/debugger/debugger_marshalls.h +++ b/core/debugger/debugger_marshalls.h @@ -31,6 +31,7 @@ #ifndef DEBUGGER_MARSHALLS_H #define DEBUGGER_MARSHALLS_H +#include "core/input/shortcut.h" #include "core/object/script_language.h" struct DebuggerMarshalls { @@ -68,6 +69,9 @@ struct DebuggerMarshalls { Array serialize(); bool deserialize(const Array &p_arr); }; + + static Array serialize_key_shortcut(const Ref &p_shortcut); + static Ref deserialize_key_shortcut(const Array &p_keys); }; #endif // DEBUGGER_MARSHALLS_H diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index b78aad17218..52fd3416fa8 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -1033,6 +1033,9 @@ void ScriptEditorDebugger::start(Ref p_peer) { _update_buttons_state(); emit_signal(SNAME("started")); + Array quit_keys = DebuggerMarshalls::serialize_key_shortcut(ED_GET_SHORTCUT("editor/stop_running_project")); + _put_msg("scene:setup_scene", quit_keys); + if (EditorSettings::get_singleton()->get_project_metadata("debug_options", "autostart_profiler", false)) { profiler->set_profiling(true); } diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index d5135f41984..caed02ae58e 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -223,11 +223,6 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { args.push_back(p_scene); } - // Pass the debugger stop shortcut to the running instance(s). - String shortcut; - VariantWriter::write_to_string(ED_GET_SHORTCUT("editor/stop_running_project"), shortcut); - OS::get_singleton()->set_environment("__GODOT_EDITOR_STOP_SHORTCUT__", shortcut); - String exec = OS::get_singleton()->get_executable_path(); int instance_count = RunInstancesDialog::get_singleton()->get_instance_count(); for (int i = 0; i < instance_count; i++) { diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index b87285ed74f..bcad4e966a2 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -30,6 +30,7 @@ #include "scene_debugger.h" +#include "core/debugger/debugger_marshalls.h" #include "core/debugger/engine_debugger.h" #include "core/io/marshalls.h" #include "core/object/script_language.h" @@ -93,6 +94,13 @@ void SceneDebugger::deinitialize() { } #ifdef DEBUG_ENABLED +void SceneDebugger::_handle_input(const Ref &p_event, const Ref &p_shortcut) { + Ref k = p_event; + if (k.is_valid() && k->is_pressed() && !k->is_echo() && p_shortcut->matches_event(k)) { + EngineDebugger::get_singleton()->send_message("request_quit", Array()); + } +} + Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured) { SceneTree *scene_tree = SceneTree::get_singleton(); if (!scene_tree) { @@ -109,7 +117,10 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra } r_captured = true; - if (p_msg == "request_scene_tree") { // Scene tree + if (p_msg == "setup_scene") { + SceneTree::get_singleton()->get_root()->connect(SceneStringName(window_input), callable_mp_static(SceneDebugger::_handle_input).bind(DebuggerMarshalls::deserialize_key_shortcut(p_args))); + + } else if (p_msg == "request_scene_tree") { // Scene tree live_editor->_send_tree(); } else if (p_msg == "save_node") { // Save node. diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h index f9dd6161aa3..1da3d526320 100644 --- a/scene/debugger/scene_debugger.h +++ b/scene/debugger/scene_debugger.h @@ -57,6 +57,8 @@ public: #ifdef DEBUG_ENABLED private: + static void _handle_input(const Ref &p_event, const Ref &p_shortcut); + static void _save_node(ObjectID id, const String &p_path); static void _set_node_owner_recursive(Node *p_node, Node *p_owner); static void _set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 045c3ae02d8..fc2fe4320b3 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -31,10 +31,8 @@ #include "window.h" #include "core/config/project_settings.h" -#include "core/debugger/engine_debugger.h" #include "core/input/shortcut.h" #include "core/string/translation_server.h" -#include "core/variant/variant_parser.h" #include "scene/gui/control.h" #include "scene/theme/theme_db.h" #include "scene/theme/theme_owner.h" @@ -1631,35 +1629,6 @@ bool Window::_can_consume_input_events() const { void Window::_window_input(const Ref &p_ev) { ERR_MAIN_THREAD_GUARD; - if (EngineDebugger::is_active()) { - // Quit from game window using the stop shortcut (F8 by default). - // The custom shortcut is provided via environment variable when running from the editor. - if (debugger_stop_shortcut.is_null()) { - String shortcut_str = OS::get_singleton()->get_environment("__GODOT_EDITOR_STOP_SHORTCUT__"); - if (!shortcut_str.is_empty()) { - Variant shortcut_var; - - VariantParser::StreamString ss; - ss.s = shortcut_str; - - String errs; - int line; - VariantParser::parse(&ss, shortcut_var, errs, line); - debugger_stop_shortcut = shortcut_var; - } - - if (debugger_stop_shortcut.is_null()) { - // Define a default shortcut if it wasn't provided or is invalid. - debugger_stop_shortcut.instantiate(); - debugger_stop_shortcut->set_events({ (Variant)InputEventKey::create_reference(Key::F8) }); - } - } - - Ref k = p_ev; - if (k.is_valid() && k->is_pressed() && !k->is_echo() && debugger_stop_shortcut->matches_event(k)) { - EngineDebugger::get_singleton()->send_message("request_quit", Array()); - } - } if (exclusive_child != nullptr) { if (!is_embedding_subwindows()) { // Not embedding, no need for event.