2
0
Эх сурвалжийг харах

Refactored input, goes all via windows now.

Also renamed Input to InputFilter because all it does is filter events.
Juan Linietsky 5 жил өмнө
parent
commit
8e6960a69e
91 өөрчлөгдсөн 819 нэмэгдсэн , 766 устгасан
  1. 6 6
      core/debugger/remote_debugger.cpp
  2. 140 151
      core/input/input_filter.cpp
  3. 16 14
      core/input/input_filter.h
  4. 0 30
      core/os/main_loop.cpp
  5. 0 11
      core/os/main_loop.h
  6. 2 2
      core/os/midi_driver.cpp
  7. 1 1
      core/os/os.cpp
  8. 3 3
      core/register_core_types.cpp
  9. 2 2
      editor/animation_track_editor.cpp
  10. 3 3
      editor/code_editor.cpp
  11. 3 3
      editor/editor_audio_buses.cpp
  12. 2 2
      editor/editor_help.cpp
  13. 12 12
      editor/editor_node.cpp
  14. 1 1
      editor/editor_plugin_settings.cpp
  15. 11 15
      editor/editor_spin_slider.cpp
  16. 2 2
      editor/export_template_manager.cpp
  17. 1 1
      editor/plugins/animation_blend_space_2d_editor.cpp
  18. 1 1
      editor/plugins/animation_blend_tree_editor_plugin.cpp
  19. 2 2
      editor/plugins/animation_player_editor_plugin.cpp
  20. 1 1
      editor/plugins/animation_state_machine_editor.cpp
  21. 1 1
      editor/plugins/animation_tree_editor_plugin.cpp
  22. 1 1
      editor/plugins/asset_library_editor_plugin.cpp
  23. 14 14
      editor/plugins/canvas_item_editor_plugin.cpp
  24. 2 2
      editor/plugins/collision_polygon_editor_plugin.cpp
  25. 2 2
      editor/plugins/curve_editor_plugin.cpp
  26. 2 2
      editor/plugins/polygon_2d_editor_plugin.cpp
  27. 3 3
      editor/plugins/script_editor_plugin.cpp
  28. 1 1
      editor/plugins/shader_editor_plugin.cpp
  29. 12 12
      editor/plugins/spatial_editor_plugin.cpp
  30. 4 4
      editor/plugins/texture_region_editor_plugin.cpp
  31. 3 3
      editor/plugins/tile_map_editor_plugin.cpp
  32. 3 3
      editor/plugins/tile_set_editor_plugin.cpp
  33. 3 3
      editor/plugins/visual_shader_editor_plugin.cpp
  34. 4 3
      editor/project_manager.cpp
  35. 3 3
      editor/property_editor.cpp
  36. 3 3
      editor/scene_tree_dock.cpp
  37. 5 6
      main/main.cpp
  38. 1 1
      modules/arkit/arkit_interface.mm
  39. 6 6
      modules/gdnative/arvr/arvr_interface_gdnative.cpp
  40. 2 2
      modules/gdnative/nativescript/nativescript.cpp
  41. 1 1
      modules/gridmap/grid_map_editor_plugin.cpp
  42. 2 2
      modules/mobile_vr/mobile_vr_interface.cpp
  43. 14 14
      modules/visual_script/visual_script_editor.cpp
  44. 5 5
      modules/visual_script/visual_script_nodes.cpp
  45. 3 1
      platform/android/java_godot_lib_jni.cpp
  46. 3 3
      platform/android/os_android.cpp
  47. 1 1
      platform/android/os_android.h
  48. 1 1
      platform/haiku/haiku_direct_window.cpp
  49. 1 1
      platform/haiku/haiku_direct_window.h
  50. 1 1
      platform/haiku/os_haiku.h
  51. 1 3
      platform/iphone/os_iphone.h
  52. 6 6
      platform/javascript/os_javascript.cpp
  53. 1 1
      platform/javascript/os_javascript.h
  54. 100 24
      platform/linuxbsd/display_server_x11.cpp
  55. 13 1
      platform/linuxbsd/display_server_x11.h
  56. 11 11
      platform/linuxbsd/joypad_linux.cpp
  57. 5 5
      platform/linuxbsd/joypad_linux.h
  58. 1 1
      platform/linuxbsd/os_linuxbsd.cpp
  59. 1 1
      platform/linuxbsd/os_linuxbsd.h
  60. 1 1
      platform/osx/joypad_osx.cpp
  61. 1 1
      platform/osx/joypad_osx.h
  62. 1 1
      platform/osx/os_osx.h
  63. 1 1
      platform/server/os_server.h
  64. 1 1
      platform/uwp/joypad_uwp.h
  65. 1 1
      platform/uwp/os_uwp.h
  66. 7 7
      platform/windows/os_windows.cpp
  67. 1 1
      platform/windows/os_windows.h
  68. 1 1
      scene/2d/canvas_item.cpp
  69. 6 6
      scene/2d/touch_screen_button.cpp
  70. 4 4
      scene/3d/arvr_nodes.cpp
  71. 3 3
      scene/gui/color_picker.cpp
  72. 0 5
      scene/gui/control.cpp
  73. 10 10
      scene/gui/graph_edit.cpp
  74. 2 2
      scene/gui/line_edit.cpp
  75. 3 3
      scene/gui/popup_menu.cpp
  76. 5 4
      scene/gui/spin_box.cpp
  77. 4 4
      scene/gui/text_edit.cpp
  78. 9 9
      scene/gui/tree.cpp
  79. 1 2
      scene/main/node.cpp
  80. 8 7
      scene/main/node.h
  81. 50 143
      scene/main/scene_tree.cpp
  82. 7 7
      scene/main/scene_tree.h
  83. 84 94
      scene/main/viewport.cpp
  84. 3 5
      scene/main/viewport.h
  85. 87 3
      scene/main/window.cpp
  86. 10 0
      scene/main/window.h
  87. 4 0
      scene/scene_string_names.cpp
  88. 4 0
      scene/scene_string_names.h
  89. 1 1
      servers/arvr/arvr_positional_tracker.cpp
  90. 24 13
      servers/display_server.cpp
  91. 20 5
      servers/display_server.h

+ 6 - 6
core/debugger/remote_debugger.cpp

@@ -33,7 +33,7 @@
 #include "core/debugger/debugger_marshalls.h"
 #include "core/debugger/debugger_marshalls.h"
 #include "core/debugger/engine_debugger.h"
 #include "core/debugger/engine_debugger.h"
 #include "core/debugger/script_debugger.h"
 #include "core/debugger/script_debugger.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 #include "core/script_language.h"
 #include "core/script_language.h"
@@ -659,9 +659,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
 
 
 	servers_profiler->skip_profile_frame = true; // Avoid frame time spike in debug.
 	servers_profiler->skip_profile_frame = true; // Avoid frame time spike in debug.
 
 
-	Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode();
-	if (mouse_mode != Input::MOUSE_MODE_VISIBLE)
-		Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+	InputFilter::MouseMode mouse_mode = InputFilter::get_singleton()->get_mouse_mode();
+	if (mouse_mode != InputFilter::MOUSE_MODE_VISIBLE)
+		InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
 
 
 	uint64_t loop_begin_usec = 0;
 	uint64_t loop_begin_usec = 0;
 	uint64_t loop_time_sec = 0;
 	uint64_t loop_time_sec = 0;
@@ -779,8 +779,8 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
 
 
 	send_message("debug_exit", Array());
 	send_message("debug_exit", Array());
 
 
-	if (mouse_mode != Input::MOUSE_MODE_VISIBLE)
-		Input::get_singleton()->set_mouse_mode(mouse_mode);
+	if (mouse_mode != InputFilter::MOUSE_MODE_VISIBLE)
+		InputFilter::get_singleton()->set_mouse_mode(mouse_mode);
 }
 }
 
 
 void RemoteDebugger::poll_events(bool p_is_idle) {
 void RemoteDebugger::poll_events(bool p_is_idle) {

+ 140 - 151
core/input/input.cpp → core/input/input_filter.cpp

@@ -1,5 +1,5 @@
 /*************************************************************************/
 /*************************************************************************/
-/*  input.cpp                                                            */
+/*  input_filter.cpp                                                     */
 /*************************************************************************/
 /*************************************************************************/
 /*                       This file is part of:                           */
 /*                       This file is part of:                           */
 /*                           GODOT ENGINE                                */
 /*                           GODOT ENGINE                                */
@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 /*************************************************************************/
 
 
-#include "input.h"
+#include "input_filter.h"
 
 
 #include "core/input/default_controller_mappings.h"
 #include "core/input/default_controller_mappings.h"
 #include "core/input/input_map.h"
 #include "core/input/input_map.h"
@@ -39,72 +39,71 @@
 #include "editor/editor_settings.h"
 #include "editor/editor_settings.h"
 #endif
 #endif
 
 
-Input *Input::singleton = NULL;
+InputFilter *InputFilter::singleton = NULL;
 
 
-void (*Input::set_mouse_mode_func)(Input::MouseMode) = nullptr;
-Input::MouseMode (*Input::get_mouse_mode_func)() = nullptr;
-void (*Input::warp_mouse_func)(const Vector2 &p_to_pos) = nullptr;
-Input::CursorShape (*Input::get_current_cursor_shape_func)() = nullptr;
-void (*Input::set_custom_mouse_cursor_func)(const RES &, Input::CursorShape, const Vector2 &) = nullptr;
+void (*InputFilter::set_mouse_mode_func)(InputFilter::MouseMode) = nullptr;
+InputFilter::MouseMode (*InputFilter::get_mouse_mode_func)() = nullptr;
+void (*InputFilter::warp_mouse_func)(const Vector2 &p_to_pos) = nullptr;
+InputFilter::CursorShape (*InputFilter::get_current_cursor_shape_func)() = nullptr;
+void (*InputFilter::set_custom_mouse_cursor_func)(const RES &, InputFilter::CursorShape, const Vector2 &) = nullptr;
 
 
-Input *Input::get_singleton() {
+InputFilter *InputFilter::get_singleton() {
 
 
 	return singleton;
 	return singleton;
 }
 }
 
 
-void Input::set_mouse_mode(MouseMode p_mode) {
+void InputFilter::set_mouse_mode(MouseMode p_mode) {
 	ERR_FAIL_INDEX((int)p_mode, 4);
 	ERR_FAIL_INDEX((int)p_mode, 4);
 	set_mouse_mode_func(p_mode);
 	set_mouse_mode_func(p_mode);
 }
 }
 
 
-Input::MouseMode Input::get_mouse_mode() const {
+InputFilter::MouseMode InputFilter::get_mouse_mode() const {
 
 
 	return get_mouse_mode_func();
 	return get_mouse_mode_func();
 }
 }
 
 
-void Input::_bind_methods() {
-
-	ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed);
-	ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed);
-	ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed);
-	ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &Input::is_action_pressed);
-	ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action"), &Input::is_action_just_pressed);
-	ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &Input::is_action_just_released);
-	ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &Input::get_action_strength);
-	ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false));
-	ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &Input::remove_joy_mapping);
-	ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &Input::joy_connection_changed);
-	ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &Input::is_joy_known);
-	ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis);
-	ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name);
-	ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &Input::get_joy_guid);
-	ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads);
-	ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength);
-	ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration);
-	ClassDB::bind_method(D_METHOD("get_joy_button_string", "button_index"), &Input::get_joy_button_string);
-	ClassDB::bind_method(D_METHOD("get_joy_button_index_from_string", "button"), &Input::get_joy_button_index_from_string);
-	ClassDB::bind_method(D_METHOD("get_joy_axis_string", "axis_index"), &Input::get_joy_axis_string);
-	ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string);
-	ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0));
-	ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &Input::stop_joy_vibration);
-	ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &Input::vibrate_handheld, DEFVAL(500));
-	ClassDB::bind_method(D_METHOD("get_gravity"), &Input::get_gravity);
-	ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
-	ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
-	ClassDB::bind_method(D_METHOD("get_gyroscope"), &Input::get_gyroscope);
-	//ClassDB::bind_method(D_METHOD("get_mouse_position"),&Input::get_mouse_position); - this is not the function you want
-	ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &Input::get_last_mouse_speed);
-	ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
-	ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode);
-	ClassDB::bind_method(D_METHOD("get_mouse_mode"), &Input::get_mouse_mode);
-	ClassDB::bind_method(D_METHOD("warp_mouse_position", "to"), &Input::warp_mouse_position);
-	ClassDB::bind_method(D_METHOD("action_press", "action", "strength"), &Input::action_press, DEFVAL(1.f));
-	ClassDB::bind_method(D_METHOD("action_release", "action"), &Input::action_release);
-	ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Input::set_default_cursor_shape, DEFVAL(CURSOR_ARROW));
-	ClassDB::bind_method(D_METHOD("get_current_cursor_shape"), &Input::get_current_cursor_shape);
-	ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
-	ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
-	ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input);
+void InputFilter::_bind_methods() {
+
+	ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &InputFilter::is_key_pressed);
+	ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &InputFilter::is_mouse_button_pressed);
+	ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &InputFilter::is_joy_button_pressed);
+	ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &InputFilter::is_action_pressed);
+	ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action"), &InputFilter::is_action_just_pressed);
+	ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &InputFilter::is_action_just_released);
+	ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &InputFilter::get_action_strength);
+	ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &InputFilter::add_joy_mapping, DEFVAL(false));
+	ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &InputFilter::remove_joy_mapping);
+	ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &InputFilter::joy_connection_changed);
+	ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &InputFilter::is_joy_known);
+	ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &InputFilter::get_joy_axis);
+	ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &InputFilter::get_joy_name);
+	ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &InputFilter::get_joy_guid);
+	ClassDB::bind_method(D_METHOD("get_connected_joypads"), &InputFilter::get_connected_joypads);
+	ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &InputFilter::get_joy_vibration_strength);
+	ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &InputFilter::get_joy_vibration_duration);
+	ClassDB::bind_method(D_METHOD("get_joy_button_string", "button_index"), &InputFilter::get_joy_button_string);
+	ClassDB::bind_method(D_METHOD("get_joy_button_index_from_string", "button"), &InputFilter::get_joy_button_index_from_string);
+	ClassDB::bind_method(D_METHOD("get_joy_axis_string", "axis_index"), &InputFilter::get_joy_axis_string);
+	ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &InputFilter::get_joy_axis_index_from_string);
+	ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &InputFilter::start_joy_vibration, DEFVAL(0));
+	ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &InputFilter::stop_joy_vibration);
+	ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &InputFilter::vibrate_handheld, DEFVAL(500));
+	ClassDB::bind_method(D_METHOD("get_gravity"), &InputFilter::get_gravity);
+	ClassDB::bind_method(D_METHOD("get_accelerometer"), &InputFilter::get_accelerometer);
+	ClassDB::bind_method(D_METHOD("get_magnetometer"), &InputFilter::get_magnetometer);
+	ClassDB::bind_method(D_METHOD("get_gyroscope"), &InputFilter::get_gyroscope);
+	ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &InputFilter::get_last_mouse_speed);
+	ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &InputFilter::get_mouse_button_mask);
+	ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &InputFilter::set_mouse_mode);
+	ClassDB::bind_method(D_METHOD("get_mouse_mode"), &InputFilter::get_mouse_mode);
+	ClassDB::bind_method(D_METHOD("warp_mouse_position", "to"), &InputFilter::warp_mouse_position);
+	ClassDB::bind_method(D_METHOD("action_press", "action", "strength"), &InputFilter::action_press, DEFVAL(1.f));
+	ClassDB::bind_method(D_METHOD("action_release", "action"), &InputFilter::action_release);
+	ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &InputFilter::set_default_cursor_shape, DEFVAL(CURSOR_ARROW));
+	ClassDB::bind_method(D_METHOD("get_current_cursor_shape"), &InputFilter::get_current_cursor_shape);
+	ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &InputFilter::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
+	ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &InputFilter::parse_input_event);
+	ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &InputFilter::set_use_accumulated_input);
 
 
 	BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
 	BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
 	BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
 	BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
@@ -132,7 +131,7 @@ void Input::_bind_methods() {
 	ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "device"), PropertyInfo(Variant::BOOL, "connected")));
 	ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "device"), PropertyInfo(Variant::BOOL, "connected")));
 }
 }
 
 
-void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+void InputFilter::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 
 
 	const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
 	const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
@@ -156,7 +155,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
 #endif
 #endif
 }
 }
 
 
-void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
+void InputFilter::SpeedTrack::update(const Vector2 &p_delta_p) {
 
 
 	uint64_t tick = OS::get_singleton()->get_ticks_usec();
 	uint64_t tick = OS::get_singleton()->get_ticks_usec();
 	uint32_t tdiff = tick - last_tick;
 	uint32_t tdiff = tick - last_tick;
@@ -180,26 +179,26 @@ void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
 	}
 	}
 }
 }
 
 
-void Input::SpeedTrack::reset() {
+void InputFilter::SpeedTrack::reset() {
 	last_tick = OS::get_singleton()->get_ticks_usec();
 	last_tick = OS::get_singleton()->get_ticks_usec();
 	speed = Vector2();
 	speed = Vector2();
 	accum_t = 0;
 	accum_t = 0;
 }
 }
 
 
-Input::SpeedTrack::SpeedTrack() {
+InputFilter::SpeedTrack::SpeedTrack() {
 
 
 	min_ref_frame = 0.1;
 	min_ref_frame = 0.1;
 	max_ref_frame = 0.3;
 	max_ref_frame = 0.3;
 	reset();
 	reset();
 }
 }
 
 
-bool Input::is_key_pressed(int p_keycode) const {
+bool InputFilter::is_key_pressed(int p_keycode) const {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	return keys_pressed.has(p_keycode);
 	return keys_pressed.has(p_keycode);
 }
 }
 
 
-bool Input::is_mouse_button_pressed(int p_button) const {
+bool InputFilter::is_mouse_button_pressed(int p_button) const {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	return (mouse_button_mask & (1 << (p_button - 1))) != 0;
 	return (mouse_button_mask & (1 << (p_button - 1))) != 0;
@@ -210,18 +209,18 @@ static int _combine_device(int p_value, int p_device) {
 	return p_value | (p_device << 20);
 	return p_value | (p_device << 20);
 }
 }
 
 
-bool Input::is_joy_button_pressed(int p_device, int p_button) const {
+bool InputFilter::is_joy_button_pressed(int p_device, int p_button) const {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	return joy_buttons_pressed.has(_combine_device(p_button, p_device));
 	return joy_buttons_pressed.has(_combine_device(p_button, p_device));
 }
 }
 
 
-bool Input::is_action_pressed(const StringName &p_action) const {
+bool InputFilter::is_action_pressed(const StringName &p_action) const {
 
 
 	return action_state.has(p_action) && action_state[p_action].pressed;
 	return action_state.has(p_action) && action_state[p_action].pressed;
 }
 }
 
 
-bool Input::is_action_just_pressed(const StringName &p_action) const {
+bool InputFilter::is_action_just_pressed(const StringName &p_action) const {
 
 
 	const Map<StringName, Action>::Element *E = action_state.find(p_action);
 	const Map<StringName, Action>::Element *E = action_state.find(p_action);
 	if (!E)
 	if (!E)
@@ -234,7 +233,7 @@ bool Input::is_action_just_pressed(const StringName &p_action) const {
 	}
 	}
 }
 }
 
 
-bool Input::is_action_just_released(const StringName &p_action) const {
+bool InputFilter::is_action_just_released(const StringName &p_action) const {
 
 
 	const Map<StringName, Action>::Element *E = action_state.find(p_action);
 	const Map<StringName, Action>::Element *E = action_state.find(p_action);
 	if (!E)
 	if (!E)
@@ -247,7 +246,7 @@ bool Input::is_action_just_released(const StringName &p_action) const {
 	}
 	}
 }
 }
 
 
-float Input::get_action_strength(const StringName &p_action) const {
+float InputFilter::get_action_strength(const StringName &p_action) const {
 	const Map<StringName, Action>::Element *E = action_state.find(p_action);
 	const Map<StringName, Action>::Element *E = action_state.find(p_action);
 	if (!E)
 	if (!E)
 		return 0.0f;
 		return 0.0f;
@@ -255,7 +254,7 @@ float Input::get_action_strength(const StringName &p_action) const {
 	return E->get().strength;
 	return E->get().strength;
 }
 }
 
 
-float Input::get_joy_axis(int p_device, int p_axis) const {
+float InputFilter::get_joy_axis(int p_device, int p_axis) const {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	int c = _combine_device(p_axis, p_device);
 	int c = _combine_device(p_axis, p_device);
@@ -266,13 +265,13 @@ float Input::get_joy_axis(int p_device, int p_axis) const {
 	}
 	}
 }
 }
 
 
-String Input::get_joy_name(int p_idx) {
+String InputFilter::get_joy_name(int p_idx) {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	return joy_names[p_idx].name;
 	return joy_names[p_idx].name;
 };
 };
 
 
-Vector2 Input::get_joy_vibration_strength(int p_device) {
+Vector2 InputFilter::get_joy_vibration_strength(int p_device) {
 	if (joy_vibration.has(p_device)) {
 	if (joy_vibration.has(p_device)) {
 		return Vector2(joy_vibration[p_device].weak_magnitude, joy_vibration[p_device].strong_magnitude);
 		return Vector2(joy_vibration[p_device].weak_magnitude, joy_vibration[p_device].strong_magnitude);
 	} else {
 	} else {
@@ -280,7 +279,7 @@ Vector2 Input::get_joy_vibration_strength(int p_device) {
 	}
 	}
 }
 }
 
 
-uint64_t Input::get_joy_vibration_timestamp(int p_device) {
+uint64_t InputFilter::get_joy_vibration_timestamp(int p_device) {
 	if (joy_vibration.has(p_device)) {
 	if (joy_vibration.has(p_device)) {
 		return joy_vibration[p_device].timestamp;
 		return joy_vibration[p_device].timestamp;
 	} else {
 	} else {
@@ -288,7 +287,7 @@ uint64_t Input::get_joy_vibration_timestamp(int p_device) {
 	}
 	}
 }
 }
 
 
-float Input::get_joy_vibration_duration(int p_device) {
+float InputFilter::get_joy_vibration_duration(int p_device) {
 	if (joy_vibration.has(p_device)) {
 	if (joy_vibration.has(p_device)) {
 		return joy_vibration[p_device].duration;
 		return joy_vibration[p_device].duration;
 	} else {
 	} else {
@@ -308,7 +307,7 @@ static String _hex_str(uint8_t p_byte) {
 	return ret;
 	return ret;
 };
 };
 
 
-void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid) {
+void InputFilter::joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid) {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	Joypad js;
 	Joypad js;
@@ -350,47 +349,36 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S
 	emit_signal("joy_connection_changed", p_idx, p_connected);
 	emit_signal("joy_connection_changed", p_idx, p_connected);
 };
 };
 
 
-Vector3 Input::get_gravity() const {
+Vector3 InputFilter::get_gravity() const {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	return gravity;
 	return gravity;
 }
 }
 
 
-Vector3 Input::get_accelerometer() const {
+Vector3 InputFilter::get_accelerometer() const {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	return accelerometer;
 	return accelerometer;
 }
 }
 
 
-Vector3 Input::get_magnetometer() const {
+Vector3 InputFilter::get_magnetometer() const {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	return magnetometer;
 	return magnetometer;
 }
 }
 
 
-Vector3 Input::get_gyroscope() const {
+Vector3 InputFilter::get_gyroscope() const {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	return gyroscope;
 	return gyroscope;
 }
 }
 
 
-void Input::parse_drop_files(const Vector<String> &p_files) {
-	if (main_loop) {
-		main_loop->drop_files(p_files);
-	}
-}
-void Input::parse_notification(int p_notification) {
-	if (main_loop) {
-		main_loop->notification(p_notification);
-	}
-}
-
-void Input::parse_input_event(const Ref<InputEvent> &p_event) {
+void InputFilter::parse_input_event(const Ref<InputEvent> &p_event) {
 
 
 	_parse_input_event_impl(p_event, false);
 	_parse_input_event_impl(p_event, false);
 }
 }
 
 
-void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
+void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
 
 
 	// Notes on mouse-touch emulation:
 	// Notes on mouse-touch emulation:
 	// - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects
 	// - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects
@@ -424,12 +412,12 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
 			set_mouse_position(pos);
 			set_mouse_position(pos);
 		}
 		}
 
 
-		if (main_loop && emulate_touch_from_mouse && !p_is_emulated && mb->get_button_index() == 1) {
+		if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && mb->get_button_index() == 1) {
 			Ref<InputEventScreenTouch> touch_event;
 			Ref<InputEventScreenTouch> touch_event;
 			touch_event.instance();
 			touch_event.instance();
 			touch_event->set_pressed(mb->is_pressed());
 			touch_event->set_pressed(mb->is_pressed());
 			touch_event->set_position(mb->get_position());
 			touch_event->set_position(mb->get_position());
-			main_loop->input_event(touch_event);
+			event_dispatch_function(touch_event);
 		}
 		}
 	}
 	}
 
 
@@ -442,7 +430,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
 			set_mouse_position(pos);
 			set_mouse_position(pos);
 		}
 		}
 
 
-		if (main_loop && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask() & 1) {
+		if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask() & 1) {
 			Ref<InputEventScreenDrag> drag_event;
 			Ref<InputEventScreenDrag> drag_event;
 			drag_event.instance();
 			drag_event.instance();
 
 
@@ -450,7 +438,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
 			drag_event->set_relative(mm->get_relative());
 			drag_event->set_relative(mm->get_relative());
 			drag_event->set_speed(mm->get_speed());
 			drag_event->set_speed(mm->get_speed());
 
 
-			main_loop->input_event(drag_event);
+			event_dispatch_function(drag_event);
 		}
 		}
 	}
 	}
 
 
@@ -548,8 +536,8 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
 
 
 	if (ge.is_valid()) {
 	if (ge.is_valid()) {
 
 
-		if (main_loop) {
-			main_loop->input_event(ge);
+		if (event_dispatch_function) {
+			event_dispatch_function(ge);
 		}
 		}
 	}
 	}
 
 
@@ -569,18 +557,18 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
 		}
 		}
 	}
 	}
 
 
-	if (main_loop)
-		main_loop->input_event(p_event);
+	if (event_dispatch_function)
+		event_dispatch_function(p_event);
 }
 }
 
 
-void Input::set_joy_axis(int p_device, int p_axis, float p_value) {
+void InputFilter::set_joy_axis(int p_device, int p_axis, float p_value) {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	int c = _combine_device(p_axis, p_device);
 	int c = _combine_device(p_axis, p_device);
 	_joy_axis[c] = p_value;
 	_joy_axis[c] = p_value;
 }
 }
 
 
-void Input::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) {
+void InputFilter::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) {
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	if (p_weak_magnitude < 0.f || p_weak_magnitude > 1.f || p_strong_magnitude < 0.f || p_strong_magnitude > 1.f) {
 	if (p_weak_magnitude < 0.f || p_weak_magnitude > 1.f || p_strong_magnitude < 0.f || p_strong_magnitude > 1.f) {
 		return;
 		return;
@@ -593,7 +581,7 @@ void Input::start_joy_vibration(int p_device, float p_weak_magnitude, float p_st
 	joy_vibration[p_device] = vibration;
 	joy_vibration[p_device] = vibration;
 }
 }
 
 
-void Input::stop_joy_vibration(int p_device) {
+void InputFilter::stop_joy_vibration(int p_device) {
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 	VibrationInfo vibration;
 	VibrationInfo vibration;
 	vibration.weak_magnitude = 0;
 	vibration.weak_magnitude = 0;
@@ -603,66 +591,63 @@ void Input::stop_joy_vibration(int p_device) {
 	joy_vibration[p_device] = vibration;
 	joy_vibration[p_device] = vibration;
 }
 }
 
 
-void Input::vibrate_handheld(int p_duration_ms) {
+void InputFilter::vibrate_handheld(int p_duration_ms) {
 	OS::get_singleton()->vibrate_handheld(p_duration_ms);
 	OS::get_singleton()->vibrate_handheld(p_duration_ms);
 }
 }
 
 
-void Input::set_gravity(const Vector3 &p_gravity) {
+void InputFilter::set_gravity(const Vector3 &p_gravity) {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 
 
 	gravity = p_gravity;
 	gravity = p_gravity;
 }
 }
 
 
-void Input::set_accelerometer(const Vector3 &p_accel) {
+void InputFilter::set_accelerometer(const Vector3 &p_accel) {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 
 
 	accelerometer = p_accel;
 	accelerometer = p_accel;
 }
 }
 
 
-void Input::set_magnetometer(const Vector3 &p_magnetometer) {
+void InputFilter::set_magnetometer(const Vector3 &p_magnetometer) {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 
 
 	magnetometer = p_magnetometer;
 	magnetometer = p_magnetometer;
 }
 }
 
 
-void Input::set_gyroscope(const Vector3 &p_gyroscope) {
+void InputFilter::set_gyroscope(const Vector3 &p_gyroscope) {
 
 
 	_THREAD_SAFE_METHOD_
 	_THREAD_SAFE_METHOD_
 
 
 	gyroscope = p_gyroscope;
 	gyroscope = p_gyroscope;
 }
 }
 
 
-void Input::set_main_loop(MainLoop *p_main_loop) {
-	main_loop = p_main_loop;
-}
-
-void Input::set_mouse_position(const Point2 &p_posf) {
+void InputFilter::set_mouse_position(const Point2 &p_posf) {
 
 
 	mouse_speed_track.update(p_posf - mouse_pos);
 	mouse_speed_track.update(p_posf - mouse_pos);
 	mouse_pos = p_posf;
 	mouse_pos = p_posf;
 }
 }
 
 
-Point2 Input::get_mouse_position() const {
+Point2 InputFilter::get_mouse_position() const {
 
 
 	return mouse_pos;
 	return mouse_pos;
 }
 }
-Point2 Input::get_last_mouse_speed() const {
+Point2 InputFilter::get_last_mouse_speed() const {
 
 
 	return mouse_speed_track.speed;
 	return mouse_speed_track.speed;
 }
 }
 
 
-int Input::get_mouse_button_mask() const {
+int InputFilter::get_mouse_button_mask() const {
 
 
 	return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state();
 	return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state();
 }
 }
 
 
-void Input::warp_mouse_position(const Vector2 &p_to) {
+void InputFilter::warp_mouse_position(const Vector2 &p_to) {
 	warp_mouse_func(p_to);
 	warp_mouse_func(p_to);
 }
 }
-Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) {
+
+Point2i InputFilter::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) {
 
 
 	// The relative distance reported for the next event after a warp is in the boundaries of the
 	// The relative distance reported for the next event after a warp is in the boundaries of the
 	// size of the rect on that axis, but it may be greater, in which case there's not problem as fmod()
 	// size of the rect on that axis, but it may be greater, in which case there's not problem as fmod()
@@ -688,10 +673,10 @@ Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, con
 	return rel_warped;
 	return rel_warped;
 }
 }
 
 
-void Input::iteration(float p_step) {
+void InputFilter::iteration(float p_step) {
 }
 }
 
 
-void Input::action_press(const StringName &p_action, float p_strength) {
+void InputFilter::action_press(const StringName &p_action, float p_strength) {
 
 
 	Action action;
 	Action action;
 
 
@@ -703,7 +688,7 @@ void Input::action_press(const StringName &p_action, float p_strength) {
 	action_state[p_action] = action;
 	action_state[p_action] = action;
 }
 }
 
 
-void Input::action_release(const StringName &p_action) {
+void InputFilter::action_release(const StringName &p_action) {
 
 
 	Action action;
 	Action action;
 
 
@@ -715,19 +700,19 @@ void Input::action_release(const StringName &p_action) {
 	action_state[p_action] = action;
 	action_state[p_action] = action;
 }
 }
 
 
-void Input::set_emulate_touch_from_mouse(bool p_emulate) {
+void InputFilter::set_emulate_touch_from_mouse(bool p_emulate) {
 
 
 	emulate_touch_from_mouse = p_emulate;
 	emulate_touch_from_mouse = p_emulate;
 }
 }
 
 
-bool Input::is_emulating_touch_from_mouse() const {
+bool InputFilter::is_emulating_touch_from_mouse() const {
 
 
 	return emulate_touch_from_mouse;
 	return emulate_touch_from_mouse;
 }
 }
 
 
 // Calling this whenever the game window is focused helps unstucking the "touch mouse"
 // Calling this whenever the game window is focused helps unstucking the "touch mouse"
 // if the OS or its abstraction class hasn't properly reported that touch pointers raised
 // if the OS or its abstraction class hasn't properly reported that touch pointers raised
-void Input::ensure_touch_mouse_raised() {
+void InputFilter::ensure_touch_mouse_raised() {
 
 
 	if (mouse_from_touch_index != -1) {
 	if (mouse_from_touch_index != -1) {
 		mouse_from_touch_index = -1;
 		mouse_from_touch_index = -1;
@@ -746,22 +731,22 @@ void Input::ensure_touch_mouse_raised() {
 	}
 	}
 }
 }
 
 
-void Input::set_emulate_mouse_from_touch(bool p_emulate) {
+void InputFilter::set_emulate_mouse_from_touch(bool p_emulate) {
 
 
 	emulate_mouse_from_touch = p_emulate;
 	emulate_mouse_from_touch = p_emulate;
 }
 }
 
 
-bool Input::is_emulating_mouse_from_touch() const {
+bool InputFilter::is_emulating_mouse_from_touch() const {
 
 
 	return emulate_mouse_from_touch;
 	return emulate_mouse_from_touch;
 }
 }
 
 
-Input::CursorShape Input::get_default_cursor_shape() const {
+InputFilter::CursorShape InputFilter::get_default_cursor_shape() const {
 
 
 	return default_shape;
 	return default_shape;
 }
 }
 
 
-void Input::set_default_cursor_shape(CursorShape p_shape) {
+void InputFilter::set_default_cursor_shape(CursorShape p_shape) {
 
 
 	if (default_shape == p_shape)
 	if (default_shape == p_shape)
 		return;
 		return;
@@ -776,19 +761,19 @@ void Input::set_default_cursor_shape(CursorShape p_shape) {
 	parse_input_event(mm);
 	parse_input_event(mm);
 }
 }
 
 
-Input::CursorShape Input::get_current_cursor_shape() const {
+InputFilter::CursorShape InputFilter::get_current_cursor_shape() const {
 
 
 	return get_current_cursor_shape_func();
 	return get_current_cursor_shape_func();
 }
 }
 
 
-void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+void InputFilter::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
 	if (Engine::get_singleton()->is_editor_hint())
 	if (Engine::get_singleton()->is_editor_hint())
 		return;
 		return;
 
 
 	set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot);
 	set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot);
 }
 }
 
 
-void Input::accumulate_input_event(const Ref<InputEvent> &p_event) {
+void InputFilter::accumulate_input_event(const Ref<InputEvent> &p_event) {
 	ERR_FAIL_COND(p_event.is_null());
 	ERR_FAIL_COND(p_event.is_null());
 
 
 	if (!use_accumulated_input) {
 	if (!use_accumulated_input) {
@@ -801,7 +786,7 @@ void Input::accumulate_input_event(const Ref<InputEvent> &p_event) {
 
 
 	accumulated_events.push_back(p_event);
 	accumulated_events.push_back(p_event);
 }
 }
-void Input::flush_accumulated_events() {
+void InputFilter::flush_accumulated_events() {
 
 
 	while (accumulated_events.front()) {
 	while (accumulated_events.front()) {
 		parse_input_event(accumulated_events.front()->get());
 		parse_input_event(accumulated_events.front()->get());
@@ -809,12 +794,12 @@ void Input::flush_accumulated_events() {
 	}
 	}
 }
 }
 
 
-void Input::set_use_accumulated_input(bool p_enable) {
+void InputFilter::set_use_accumulated_input(bool p_enable) {
 
 
 	use_accumulated_input = p_enable;
 	use_accumulated_input = p_enable;
 }
 }
 
 
-void Input::release_pressed_events() {
+void InputFilter::release_pressed_events() {
 
 
 	flush_accumulated_events(); // this is needed to release actions strengths
 	flush_accumulated_events(); // this is needed to release actions strengths
 
 
@@ -822,13 +807,17 @@ void Input::release_pressed_events() {
 	joy_buttons_pressed.clear();
 	joy_buttons_pressed.clear();
 	_joy_axis.clear();
 	_joy_axis.clear();
 
 
-	for (Map<StringName, Input::Action>::Element *E = action_state.front(); E; E = E->next()) {
+	for (Map<StringName, InputFilter::Action>::Element *E = action_state.front(); E; E = E->next()) {
 		if (E->get().pressed)
 		if (E->get().pressed)
 			action_release(E->key());
 			action_release(E->key());
 	}
 	}
 }
 }
 
 
-void Input::joy_button(int p_device, int p_button, bool p_pressed) {
+void InputFilter::set_event_dispatch_function(EventDispatchFunc p_function) {
+	event_dispatch_function = p_function;
+}
+
+void InputFilter::joy_button(int p_device, int p_button, bool p_pressed) {
 
 
 	_THREAD_SAFE_METHOD_;
 	_THREAD_SAFE_METHOD_;
 	Joypad &joy = joy_names[p_device];
 	Joypad &joy = joy_names[p_device];
@@ -867,7 +856,7 @@ void Input::joy_button(int p_device, int p_button, bool p_pressed) {
 	// no event?
 	// no event?
 }
 }
 
 
-void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
+void InputFilter::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
 
 
 	_THREAD_SAFE_METHOD_;
 	_THREAD_SAFE_METHOD_;
 
 
@@ -982,7 +971,7 @@ void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
 	//printf("invalid mapping\n");
 	//printf("invalid mapping\n");
 }
 }
 
 
-void Input::joy_hat(int p_device, int p_val) {
+void InputFilter::joy_hat(int p_device, int p_val) {
 
 
 	_THREAD_SAFE_METHOD_;
 	_THREAD_SAFE_METHOD_;
 	const Joypad &joy = joy_names[p_device];
 	const Joypad &joy = joy_names[p_device];
@@ -1014,7 +1003,7 @@ void Input::joy_hat(int p_device, int p_val) {
 	joy_names[p_device].hat_current = p_val;
 	joy_names[p_device].hat_current = p_val;
 }
 }
 
 
-void Input::_button_event(int p_device, int p_index, bool p_pressed) {
+void InputFilter::_button_event(int p_device, int p_index, bool p_pressed) {
 
 
 	Ref<InputEventJoypadButton> ievent;
 	Ref<InputEventJoypadButton> ievent;
 	ievent.instance();
 	ievent.instance();
@@ -1025,7 +1014,7 @@ void Input::_button_event(int p_device, int p_index, bool p_pressed) {
 	parse_input_event(ievent);
 	parse_input_event(ievent);
 }
 }
 
 
-void Input::_axis_event(int p_device, int p_axis, float p_value) {
+void InputFilter::_axis_event(int p_device, int p_axis, float p_value) {
 
 
 	Ref<InputEventJoypadMotion> ievent;
 	Ref<InputEventJoypadMotion> ievent;
 	ievent.instance();
 	ievent.instance();
@@ -1036,7 +1025,7 @@ void Input::_axis_event(int p_device, int p_axis, float p_value) {
 	parse_input_event(ievent);
 	parse_input_event(ievent);
 };
 };
 
 
-Input::JoyEvent Input::_find_to_event(String p_to) {
+InputFilter::JoyEvent InputFilter::_find_to_event(String p_to) {
 
 
 	// string names of the SDL buttons in the same order as input_event.h godot buttons
 	// string names of the SDL buttons in the same order as input_event.h godot buttons
 	static const char *buttons[] = { "a", "b", "x", "y", "leftshoulder", "rightshoulder", "lefttrigger", "righttrigger", "leftstick", "rightstick", "back", "start", "dpup", "dpdown", "dpleft", "dpright", "guide", NULL };
 	static const char *buttons[] = { "a", "b", "x", "y", "leftshoulder", "rightshoulder", "lefttrigger", "righttrigger", "leftstick", "rightstick", "back", "start", "dpup", "dpdown", "dpleft", "dpright", "guide", NULL };
@@ -1074,7 +1063,7 @@ Input::JoyEvent Input::_find_to_event(String p_to) {
 	return ret;
 	return ret;
 };
 };
 
 
-void Input::parse_mapping(String p_mapping) {
+void InputFilter::parse_mapping(String p_mapping) {
 
 
 	_THREAD_SAFE_METHOD_;
 	_THREAD_SAFE_METHOD_;
 	JoyDeviceMapping mapping;
 	JoyDeviceMapping mapping;
@@ -1139,7 +1128,7 @@ void Input::parse_mapping(String p_mapping) {
 	//printf("added mapping with uuid %ls\n", mapping.uid.c_str());
 	//printf("added mapping with uuid %ls\n", mapping.uid.c_str());
 };
 };
 
 
-void Input::add_joy_mapping(String p_mapping, bool p_update_existing) {
+void InputFilter::add_joy_mapping(String p_mapping, bool p_update_existing) {
 	parse_mapping(p_mapping);
 	parse_mapping(p_mapping);
 	if (p_update_existing) {
 	if (p_update_existing) {
 		Vector<String> entry = p_mapping.split(",");
 		Vector<String> entry = p_mapping.split(",");
@@ -1152,7 +1141,7 @@ void Input::add_joy_mapping(String p_mapping, bool p_update_existing) {
 	}
 	}
 }
 }
 
 
-void Input::remove_joy_mapping(String p_guid) {
+void InputFilter::remove_joy_mapping(String p_guid) {
 	for (int i = map_db.size() - 1; i >= 0; i--) {
 	for (int i = map_db.size() - 1; i >= 0; i--) {
 		if (p_guid == map_db[i].uid) {
 		if (p_guid == map_db[i].uid) {
 			map_db.remove(i);
 			map_db.remove(i);
@@ -1165,7 +1154,7 @@ void Input::remove_joy_mapping(String p_guid) {
 	}
 	}
 }
 }
 
 
-void Input::set_fallback_mapping(String p_guid) {
+void InputFilter::set_fallback_mapping(String p_guid) {
 
 
 	for (int i = 0; i < map_db.size(); i++) {
 	for (int i = 0; i < map_db.size(); i++) {
 		if (map_db[i].uid == p_guid) {
 		if (map_db[i].uid == p_guid) {
@@ -1176,17 +1165,17 @@ void Input::set_fallback_mapping(String p_guid) {
 }
 }
 
 
 //platforms that use the remapping system can override and call to these ones
 //platforms that use the remapping system can override and call to these ones
-bool Input::is_joy_known(int p_device) {
+bool InputFilter::is_joy_known(int p_device) {
 	int mapping = joy_names[p_device].mapping;
 	int mapping = joy_names[p_device].mapping;
 	return mapping != -1 ? (mapping != fallback_mapping) : false;
 	return mapping != -1 ? (mapping != fallback_mapping) : false;
 }
 }
 
 
-String Input::get_joy_guid(int p_device) const {
+String InputFilter::get_joy_guid(int p_device) const {
 	ERR_FAIL_COND_V(!joy_names.has(p_device), "");
 	ERR_FAIL_COND_V(!joy_names.has(p_device), "");
 	return joy_names[p_device].uid;
 	return joy_names[p_device].uid;
 }
 }
 
 
-Array Input::get_connected_joypads() {
+Array InputFilter::get_connected_joypads() {
 	Array ret;
 	Array ret;
 	Map<int, Joypad>::Element *elem = joy_names.front();
 	Map<int, Joypad>::Element *elem = joy_names.front();
 	while (elem) {
 	while (elem) {
@@ -1230,12 +1219,12 @@ static const char *_axes[JOY_AXIS_MAX] = {
 	""
 	""
 };
 };
 
 
-String Input::get_joy_button_string(int p_button) {
+String InputFilter::get_joy_button_string(int p_button) {
 	ERR_FAIL_INDEX_V(p_button, JOY_BUTTON_MAX, "");
 	ERR_FAIL_INDEX_V(p_button, JOY_BUTTON_MAX, "");
 	return _buttons[p_button];
 	return _buttons[p_button];
 }
 }
 
 
-int Input::get_joy_button_index_from_string(String p_button) {
+int InputFilter::get_joy_button_index_from_string(String p_button) {
 	for (int i = 0; i < JOY_BUTTON_MAX; i++) {
 	for (int i = 0; i < JOY_BUTTON_MAX; i++) {
 		if (p_button == _buttons[i]) {
 		if (p_button == _buttons[i]) {
 			return i;
 			return i;
@@ -1244,7 +1233,7 @@ int Input::get_joy_button_index_from_string(String p_button) {
 	ERR_FAIL_V(-1);
 	ERR_FAIL_V(-1);
 }
 }
 
 
-int Input::get_unused_joy_id() {
+int InputFilter::get_unused_joy_id() {
 	for (int i = 0; i < JOYPADS_MAX; i++) {
 	for (int i = 0; i < JOYPADS_MAX; i++) {
 		if (!joy_names.has(i) || !joy_names[i].connected) {
 		if (!joy_names.has(i) || !joy_names[i].connected) {
 			return i;
 			return i;
@@ -1253,12 +1242,12 @@ int Input::get_unused_joy_id() {
 	return -1;
 	return -1;
 }
 }
 
 
-String Input::get_joy_axis_string(int p_axis) {
+String InputFilter::get_joy_axis_string(int p_axis) {
 	ERR_FAIL_INDEX_V(p_axis, JOY_AXIS_MAX, "");
 	ERR_FAIL_INDEX_V(p_axis, JOY_AXIS_MAX, "");
 	return _axes[p_axis];
 	return _axes[p_axis];
 }
 }
 
 
-int Input::get_joy_axis_index_from_string(String p_axis) {
+int InputFilter::get_joy_axis_index_from_string(String p_axis) {
 	for (int i = 0; i < JOY_AXIS_MAX; i++) {
 	for (int i = 0; i < JOY_AXIS_MAX; i++) {
 		if (p_axis == _axes[i]) {
 		if (p_axis == _axes[i]) {
 			return i;
 			return i;
@@ -1267,7 +1256,7 @@ int Input::get_joy_axis_index_from_string(String p_axis) {
 	ERR_FAIL_V(-1);
 	ERR_FAIL_V(-1);
 }
 }
 
 
-Input::Input() {
+InputFilter::InputFilter() {
 
 
 	singleton = this;
 	singleton = this;
 	use_accumulated_input = true;
 	use_accumulated_input = true;
@@ -1276,7 +1265,7 @@ Input::Input() {
 	emulate_touch_from_mouse = false;
 	emulate_touch_from_mouse = false;
 	emulate_mouse_from_touch = false;
 	emulate_mouse_from_touch = false;
 	mouse_from_touch_index = -1;
 	mouse_from_touch_index = -1;
-	main_loop = NULL;
+	event_dispatch_function = nullptr;
 	default_shape = CURSOR_ARROW;
 	default_shape = CURSOR_ARROW;
 
 
 	hat_map_default[HAT_UP].type = TYPE_BUTTON;
 	hat_map_default[HAT_UP].type = TYPE_BUTTON;

+ 16 - 14
core/input/input.h → core/input/input_filter.h

@@ -1,5 +1,5 @@
 /*************************************************************************/
 /*************************************************************************/
-/*  input.h                                                              */
+/*  input_filter.h                                                       */
 /*************************************************************************/
 /*************************************************************************/
 /*                       This file is part of:                           */
 /*                       This file is part of:                           */
 /*                           GODOT ENGINE                                */
 /*                           GODOT ENGINE                                */
@@ -31,16 +31,16 @@
 #ifndef INPUT_H
 #ifndef INPUT_H
 #define INPUT_H
 #define INPUT_H
 
 
+#include "core/input/input_event.h"
 #include "core/object.h"
 #include "core/object.h"
-#include "core/os/main_loop.h"
 #include "core/os/thread_safe.h"
 #include "core/os/thread_safe.h"
 
 
-class Input : public Object {
+class InputFilter : public Object {
 
 
-	GDCLASS(Input, Object);
+	GDCLASS(InputFilter, Object);
 	_THREAD_SAFE_CLASS_
 	_THREAD_SAFE_CLASS_
 
 
-	static Input *singleton;
+	static InputFilter *singleton;
 
 
 public:
 public:
 	enum MouseMode {
 	enum MouseMode {
@@ -97,6 +97,8 @@ public:
 		float value;
 		float value;
 	};
 	};
 
 
+	typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
+
 private:
 private:
 	int mouse_button_mask;
 	int mouse_button_mask;
 
 
@@ -110,7 +112,6 @@ private:
 	Vector3 gyroscope;
 	Vector3 gyroscope;
 	Vector2 mouse_pos;
 	Vector2 mouse_pos;
 	int64_t mouse_window;
 	int64_t mouse_window;
-	MainLoop *main_loop;
 
 
 	struct Action {
 	struct Action {
 		uint64_t physics_frame;
 		uint64_t physics_frame;
@@ -228,6 +229,8 @@ private:
 	static CursorShape (*get_current_cursor_shape_func)();
 	static CursorShape (*get_current_cursor_shape_func)();
 	static void (*set_custom_mouse_cursor_func)(const RES &, CursorShape, const Vector2 &);
 	static void (*set_custom_mouse_cursor_func)(const RES &, CursorShape, const Vector2 &);
 
 
+	EventDispatchFunc event_dispatch_function;
+
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();
 
 
@@ -236,7 +239,7 @@ public:
 	MouseMode get_mouse_mode() const;
 	MouseMode get_mouse_mode() const;
 	void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
 	void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
 
 
-	static Input *get_singleton();
+	static InputFilter *get_singleton();
 
 
 	bool is_key_pressed(int p_keycode) const;
 	bool is_key_pressed(int p_keycode) const;
 	bool is_mouse_button_pressed(int p_button) const;
 	bool is_mouse_button_pressed(int p_button) const;
@@ -267,8 +270,6 @@ public:
 	void warp_mouse_position(const Vector2 &p_to);
 	void warp_mouse_position(const Vector2 &p_to);
 	Point2i warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect);
 	Point2i warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect);
 
 
-	void parse_drop_files(const Vector<String> &p_files);
-	void parse_notification(int p_notification);
 	void parse_input_event(const Ref<InputEvent> &p_event);
 	void parse_input_event(const Ref<InputEvent> &p_event);
 
 
 	void set_gravity(const Vector3 &p_gravity);
 	void set_gravity(const Vector3 &p_gravity);
@@ -281,7 +282,6 @@ public:
 	void stop_joy_vibration(int p_device);
 	void stop_joy_vibration(int p_device);
 	void vibrate_handheld(int p_duration_ms = 500);
 	void vibrate_handheld(int p_duration_ms = 500);
 
 
-	void set_main_loop(MainLoop *p_main_loop);
 	void set_mouse_position(const Point2 &p_posf);
 	void set_mouse_position(const Point2 &p_posf);
 
 
 	void action_press(const StringName &p_action, float p_strength = 1.f);
 	void action_press(const StringName &p_action, float p_strength = 1.f);
@@ -299,7 +299,7 @@ public:
 	CursorShape get_default_cursor_shape() const;
 	CursorShape get_default_cursor_shape() const;
 	void set_default_cursor_shape(CursorShape p_shape);
 	void set_default_cursor_shape(CursorShape p_shape);
 	CursorShape get_current_cursor_shape() const;
 	CursorShape get_current_cursor_shape() const;
-	void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
+	void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = InputFilter::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
 
 
 	void parse_mapping(String p_mapping);
 	void parse_mapping(String p_mapping);
 	void joy_button(int p_device, int p_button, bool p_pressed);
 	void joy_button(int p_device, int p_button, bool p_pressed);
@@ -326,10 +326,12 @@ public:
 
 
 	void release_pressed_events();
 	void release_pressed_events();
 
 
-	Input();
+	void set_event_dispatch_function(EventDispatchFunc p_function);
+
+	InputFilter();
 };
 };
 
 
-VARIANT_ENUM_CAST(Input::MouseMode);
-VARIANT_ENUM_CAST(Input::CursorShape);
+VARIANT_ENUM_CAST(InputFilter::MouseMode);
+VARIANT_ENUM_CAST(InputFilter::CursorShape);
 
 
 #endif // INPUT_H
 #endif // INPUT_H

+ 0 - 30
core/os/main_loop.cpp

@@ -34,30 +34,18 @@
 
 
 void MainLoop::_bind_methods() {
 void MainLoop::_bind_methods() {
 
 
-	ClassDB::bind_method(D_METHOD("input_event", "event"), &MainLoop::input_event);
-	ClassDB::bind_method(D_METHOD("input_text", "text"), &MainLoop::input_text);
 	ClassDB::bind_method(D_METHOD("init"), &MainLoop::init);
 	ClassDB::bind_method(D_METHOD("init"), &MainLoop::init);
 	ClassDB::bind_method(D_METHOD("iteration", "delta"), &MainLoop::iteration);
 	ClassDB::bind_method(D_METHOD("iteration", "delta"), &MainLoop::iteration);
 	ClassDB::bind_method(D_METHOD("idle", "delta"), &MainLoop::idle);
 	ClassDB::bind_method(D_METHOD("idle", "delta"), &MainLoop::idle);
 	ClassDB::bind_method(D_METHOD("finish"), &MainLoop::finish);
 	ClassDB::bind_method(D_METHOD("finish"), &MainLoop::finish);
 
 
-	BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
-	BIND_VMETHOD(MethodInfo("_input_text", PropertyInfo(Variant::STRING, "text")));
 	BIND_VMETHOD(MethodInfo("_initialize"));
 	BIND_VMETHOD(MethodInfo("_initialize"));
 	BIND_VMETHOD(MethodInfo(Variant::BOOL, "_iteration", PropertyInfo(Variant::FLOAT, "delta")));
 	BIND_VMETHOD(MethodInfo(Variant::BOOL, "_iteration", PropertyInfo(Variant::FLOAT, "delta")));
 	BIND_VMETHOD(MethodInfo(Variant::BOOL, "_idle", PropertyInfo(Variant::FLOAT, "delta")));
 	BIND_VMETHOD(MethodInfo(Variant::BOOL, "_idle", PropertyInfo(Variant::FLOAT, "delta")));
-	BIND_VMETHOD(MethodInfo("_drop_files", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "from_screen")));
 	BIND_VMETHOD(MethodInfo("_finalize"));
 	BIND_VMETHOD(MethodInfo("_finalize"));
 
 
 	BIND_VMETHOD(MethodInfo("_global_menu_action", PropertyInfo(Variant::NIL, "id"), PropertyInfo(Variant::NIL, "meta")));
 	BIND_VMETHOD(MethodInfo("_global_menu_action", PropertyInfo(Variant::NIL, "id"), PropertyInfo(Variant::NIL, "meta")));
 
 
-	BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER);
-	BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT);
-	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN);
-	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT);
-	BIND_CONSTANT(NOTIFICATION_WM_QUIT_REQUEST);
-	BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST);
-	BIND_CONSTANT(NOTIFICATION_WM_UNFOCUS_REQUEST);
 	BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
 	BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
 	BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
 	BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
@@ -80,18 +68,6 @@ MainLoop::MainLoop() {
 MainLoop::~MainLoop() {
 MainLoop::~MainLoop() {
 }
 }
 
 
-void MainLoop::input_text(const String &p_text) {
-
-	if (get_script_instance())
-		get_script_instance()->call("_input_text", p_text);
-}
-
-void MainLoop::input_event(const Ref<InputEvent> &p_event) {
-
-	if (get_script_instance())
-		get_script_instance()->call("_input_event", p_event);
-}
-
 void MainLoop::init() {
 void MainLoop::init() {
 
 
 	if (init_script.is_valid())
 	if (init_script.is_valid())
@@ -115,12 +91,6 @@ bool MainLoop::idle(float p_time) {
 	return false;
 	return false;
 }
 }
 
 
-void MainLoop::drop_files(const Vector<String> &p_files, int p_from_screen) {
-
-	if (get_script_instance())
-		get_script_instance()->call("_drop_files", p_files, p_from_screen);
-}
-
 void MainLoop::global_menu_action(const Variant &p_id, const Variant &p_meta) {
 void MainLoop::global_menu_action(const Variant &p_id, const Variant &p_meta) {
 
 
 	if (get_script_instance())
 	if (get_script_instance())

+ 0 - 11
core/os/main_loop.h

@@ -48,13 +48,6 @@ protected:
 public:
 public:
 	enum {
 	enum {
 		//make sure these are replicated in Node
 		//make sure these are replicated in Node
-		NOTIFICATION_WM_MOUSE_ENTER = 1002,
-		NOTIFICATION_WM_MOUSE_EXIT = 1003,
-		NOTIFICATION_WM_FOCUS_IN = 1004,
-		NOTIFICATION_WM_FOCUS_OUT = 1005,
-		NOTIFICATION_WM_QUIT_REQUEST = 1006,
-		NOTIFICATION_WM_GO_BACK_REQUEST = 1007,
-		NOTIFICATION_WM_UNFOCUS_REQUEST = 1008,
 		NOTIFICATION_OS_MEMORY_WARNING = 1009,
 		NOTIFICATION_OS_MEMORY_WARNING = 1009,
 		NOTIFICATION_TRANSLATION_CHANGED = 1010,
 		NOTIFICATION_TRANSLATION_CHANGED = 1010,
 		NOTIFICATION_WM_ABOUT = 1011,
 		NOTIFICATION_WM_ABOUT = 1011,
@@ -64,15 +57,11 @@ public:
 		NOTIFICATION_APP_PAUSED = 1015,
 		NOTIFICATION_APP_PAUSED = 1015,
 	};
 	};
 
 
-	virtual void input_event(const Ref<InputEvent> &p_event);
-	virtual void input_text(const String &p_text);
-
 	virtual void init();
 	virtual void init();
 	virtual bool iteration(float p_time);
 	virtual bool iteration(float p_time);
 	virtual bool idle(float p_time);
 	virtual bool idle(float p_time);
 	virtual void finish();
 	virtual void finish();
 
 
-	virtual void drop_files(const Vector<String> &p_files, int p_from_screen = 0);
 	virtual void global_menu_action(const Variant &p_id, const Variant &p_meta);
 	virtual void global_menu_action(const Variant &p_id, const Variant &p_meta);
 
 
 	void set_init_script(const Ref<Script> &p_init_script);
 	void set_init_script(const Ref<Script> &p_init_script);

+ 2 - 2
core/os/midi_driver.cpp

@@ -30,7 +30,7 @@
 
 
 #include "midi_driver.h"
 #include "midi_driver.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 
 
 uint8_t MIDIDriver::last_received_message = 0x00;
 uint8_t MIDIDriver::last_received_message = 0x00;
@@ -117,7 +117,7 @@ void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_
 			break;
 			break;
 	}
 	}
 
 
-	Input *id = Input::get_singleton();
+	InputFilter *id = InputFilter::get_singleton();
 	id->parse_input_event(event);
 	id->parse_input_event(event);
 }
 }
 
 

+ 1 - 1
core/os/os.cpp

@@ -30,7 +30,7 @@
 
 
 #include "os.h"
 #include "os.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/dir_access.h"
 #include "core/os/dir_access.h"
 #include "core/os/file_access.h"
 #include "core/os/file_access.h"
 #include "core/os/midi_driver.h"
 #include "core/os/midi_driver.h"

+ 3 - 3
core/register_core_types.cpp

@@ -38,7 +38,7 @@
 #include "core/crypto/hashing_context.h"
 #include "core/crypto/hashing_context.h"
 #include "core/engine.h"
 #include "core/engine.h"
 #include "core/func_ref.h"
 #include "core/func_ref.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/input/input_map.h"
 #include "core/input/input_map.h"
 #include "core/io/config_file.h"
 #include "core/io/config_file.h"
 #include "core/io/dtls_server.h"
 #include "core/io/dtls_server.h"
@@ -248,7 +248,7 @@ void register_core_singletons() {
 	ClassDB::register_class<_ClassDB>();
 	ClassDB::register_class<_ClassDB>();
 	ClassDB::register_class<_Marshalls>();
 	ClassDB::register_class<_Marshalls>();
 	ClassDB::register_class<TranslationServer>();
 	ClassDB::register_class<TranslationServer>();
-	ClassDB::register_virtual_class<Input>();
+	ClassDB::register_virtual_class<InputFilter>();
 	ClassDB::register_class<InputMap>();
 	ClassDB::register_class<InputMap>();
 	ClassDB::register_class<_JSON>();
 	ClassDB::register_class<_JSON>();
 	ClassDB::register_class<Expression>();
 	ClassDB::register_class<Expression>();
@@ -263,7 +263,7 @@ void register_core_singletons() {
 	Engine::get_singleton()->add_singleton(Engine::Singleton("ClassDB", _classdb));
 	Engine::get_singleton()->add_singleton(Engine::Singleton("ClassDB", _classdb));
 	Engine::get_singleton()->add_singleton(Engine::Singleton("Marshalls", _Marshalls::get_singleton()));
 	Engine::get_singleton()->add_singleton(Engine::Singleton("Marshalls", _Marshalls::get_singleton()));
 	Engine::get_singleton()->add_singleton(Engine::Singleton("TranslationServer", TranslationServer::get_singleton()));
 	Engine::get_singleton()->add_singleton(Engine::Singleton("TranslationServer", TranslationServer::get_singleton()));
-	Engine::get_singleton()->add_singleton(Engine::Singleton("Input", Input::get_singleton()));
+	Engine::get_singleton()->add_singleton(Engine::Singleton("Input", InputFilter::get_singleton()));
 	Engine::get_singleton()->add_singleton(Engine::Singleton("InputMap", InputMap::get_singleton()));
 	Engine::get_singleton()->add_singleton(Engine::Singleton("InputMap", InputMap::get_singleton()));
 	Engine::get_singleton()->add_singleton(Engine::Singleton("JSON", _JSON::get_singleton()));
 	Engine::get_singleton()->add_singleton(Engine::Singleton("JSON", _JSON::get_singleton()));
 }
 }

+ 2 - 2
editor/animation_track_editor.cpp

@@ -31,7 +31,7 @@
 #include "animation_track_editor.h"
 #include "animation_track_editor.h"
 
 
 #include "animation_track_editor_plugins.h"
 #include "animation_track_editor_plugins.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "editor/animation_bezier_editor.h"
 #include "editor/animation_bezier_editor.h"
 #include "editor/plugins/animation_player_editor_plugin.h"
 #include "editor/plugins/animation_player_editor_plugin.h"
@@ -4095,7 +4095,7 @@ bool AnimationTrackEditor::is_selection_active() const {
 }
 }
 
 
 bool AnimationTrackEditor::is_snap_enabled() const {
 bool AnimationTrackEditor::is_snap_enabled() const {
-	return snap->is_pressed() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+	return snap->is_pressed() ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
 }
 }
 
 
 void AnimationTrackEditor::_update_tracks() {
 void AnimationTrackEditor::_update_tracks() {

+ 3 - 3
editor/code_editor.cpp

@@ -30,7 +30,7 @@
 
 
 #include "code_editor.h"
 #include "code_editor.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/string_builder.h"
 #include "core/string_builder.h"
 #include "editor/editor_scale.h"
 #include "editor/editor_scale.h"
@@ -505,7 +505,7 @@ void FindReplaceBar::_search_text_changed(const String &p_text) {
 
 
 void FindReplaceBar::_search_text_entered(const String &p_text) {
 void FindReplaceBar::_search_text_entered(const String &p_text) {
 
 
-	if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 		search_prev();
 		search_prev();
 	} else {
 	} else {
 		search_next();
 		search_next();
@@ -517,7 +517,7 @@ void FindReplaceBar::_replace_text_entered(const String &p_text) {
 	if (selection_only->is_pressed() && text_edit->is_selection_active()) {
 	if (selection_only->is_pressed() && text_edit->is_selection_active()) {
 		_replace_all();
 		_replace_all();
 		_hide_bar();
 		_hide_bar();
-	} else if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+	} else if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 		_replace();
 		_replace();
 		search_prev();
 		search_prev();
 	} else {
 	} else {

+ 3 - 3
editor/editor_audio_buses.cpp

@@ -30,7 +30,7 @@
 
 
 #include "editor_audio_buses.h"
 #include "editor_audio_buses.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/resource_saver.h"
 #include "core/io/resource_saver.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "editor_node.h"
 #include "editor_node.h"
@@ -325,7 +325,7 @@ void EditorAudioBus::_volume_changed(float p_normalized) {
 
 
 	const float p_db = this->_normalized_volume_to_scaled_db(p_normalized);
 	const float p_db = this->_normalized_volume_to_scaled_db(p_normalized);
 
 
-	if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
 		// Snap the value when holding Ctrl for easier editing.
 		// Snap the value when holding Ctrl for easier editing.
 		// To do so, it needs to be converted back to normalized volume (as the slider uses that unit).
 		// To do so, it needs to be converted back to normalized volume (as the slider uses that unit).
 		slider->set_value(_scaled_db_to_normalized_volume(Math::round(p_db)));
 		slider->set_value(_scaled_db_to_normalized_volume(Math::round(p_db)));
@@ -386,7 +386,7 @@ float EditorAudioBus::_scaled_db_to_normalized_volume(float db) {
 void EditorAudioBus::_show_value(float slider_value) {
 void EditorAudioBus::_show_value(float slider_value) {
 
 
 	float db;
 	float db;
-	if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
 		// Display the correct (snapped) value when holding Ctrl
 		// Display the correct (snapped) value when holding Ctrl
 		db = Math::round(_normalized_volume_to_scaled_db(slider_value));
 		db = Math::round(_normalized_volume_to_scaled_db(slider_value));
 	} else {
 	} else {

+ 2 - 2
editor/editor_help.cpp

@@ -30,7 +30,7 @@
 
 
 #include "editor_help.h"
 #include "editor_help.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "doc_data_compressed.gen.h"
 #include "doc_data_compressed.gen.h"
 #include "editor/plugins/script_editor_plugin.h"
 #include "editor/plugins/script_editor_plugin.h"
@@ -1828,7 +1828,7 @@ void FindBar::_search_text_changed(const String &p_text) {
 
 
 void FindBar::_search_text_entered(const String &p_text) {
 void FindBar::_search_text_entered(const String &p_text) {
 
 
-	if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 		search_prev();
 		search_prev();
 	} else {
 	} else {
 		search_next();
 		search_next();

+ 12 - 12
editor/editor_node.cpp

@@ -32,7 +32,7 @@
 
 
 #include "core/bind/core_bind.h"
 #include "core/bind/core_bind.h"
 #include "core/class_db.h"
 #include "core/class_db.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/config_file.h"
 #include "core/io/config_file.h"
 #include "core/io/image_loader.h"
 #include "core/io/image_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
@@ -303,7 +303,7 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
 		}
 		}
 
 
 		if (old_editor != editor_plugin_screen) {
 		if (old_editor != editor_plugin_screen) {
-			get_tree()->set_input_as_handled();
+			get_tree()->get_root()->set_input_as_handled();
 		}
 		}
 	}
 	}
 }
 }
@@ -380,7 +380,7 @@ void EditorNode::_notification(int p_what) {
 			get_tree()->get_root()->set_as_audio_listener(false);
 			get_tree()->get_root()->set_as_audio_listener(false);
 			get_tree()->get_root()->set_as_audio_listener_2d(false);
 			get_tree()->get_root()->set_as_audio_listener_2d(false);
 			get_tree()->set_auto_accept_quit(false);
 			get_tree()->set_auto_accept_quit(false);
-			get_tree()->connect("files_dropped", callable_mp(this, &EditorNode::_dropped_files));
+			get_tree()->get_root()->connect("files_dropped", callable_mp(this, &EditorNode::_dropped_files));
 			get_tree()->connect("global_menu_action", callable_mp(this, &EditorNode::_global_menu_action));
 			get_tree()->connect("global_menu_action", callable_mp(this, &EditorNode::_global_menu_action));
 
 
 			/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
 			/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
@@ -423,7 +423,7 @@ void EditorNode::_notification(int p_what) {
 			/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
 			/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
 		} break;
 		} break;
 
 
-		case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
+		case NOTIFICATION_WM_FOCUS_IN: {
 
 
 			// Restore the original FPS cap after focusing back on the editor
 			// Restore the original FPS cap after focusing back on the editor
 			OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec")));
 			OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec")));
@@ -431,18 +431,18 @@ void EditorNode::_notification(int p_what) {
 			EditorFileSystem::get_singleton()->scan_changes();
 			EditorFileSystem::get_singleton()->scan_changes();
 		} break;
 		} break;
 
 
-		case MainLoop::NOTIFICATION_WM_FOCUS_OUT: {
+		case NOTIFICATION_WM_FOCUS_OUT: {
 
 
 			// Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused
 			// Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused
 			OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec")));
 			OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec")));
 		} break;
 		} break;
 
 
-		case MainLoop::NOTIFICATION_WM_ABOUT: {
+		case NOTIFICATION_WM_ABOUT: {
 
 
 			show_about();
 			show_about();
 		} break;
 		} break;
 
 
-		case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: {
+		case NOTIFICATION_WM_CLOSE_REQUEST: {
 
 
 			_menu_option_confirm(FILE_QUIT, false);
 			_menu_option_confirm(FILE_QUIT, false);
 		} break;
 		} break;
@@ -2347,7 +2347,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
 
 
 		case EDIT_UNDO: {
 		case EDIT_UNDO: {
 
 
-			if (Input::get_singleton()->get_mouse_button_mask() & 0x7) {
+			if (InputFilter::get_singleton()->get_mouse_button_mask() & 0x7) {
 				log->add_message("Can't undo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR);
 				log->add_message("Can't undo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR);
 			} else {
 			} else {
 				String action = editor_data.get_undo_redo().get_current_action_name();
 				String action = editor_data.get_undo_redo().get_current_action_name();
@@ -2361,7 +2361,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
 		} break;
 		} break;
 		case EDIT_REDO: {
 		case EDIT_REDO: {
 
 
-			if (Input::get_singleton()->get_mouse_button_mask() & 0x7) {
+			if (InputFilter::get_singleton()->get_mouse_button_mask() & 0x7) {
 				log->add_message("Can't redo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR);
 				log->add_message("Can't redo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR);
 			} else {
 			} else {
 				if (!editor_data.get_undo_redo().redo()) {
 				if (!editor_data.get_undo_redo().redo()) {
@@ -5472,7 +5472,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
 
 
 EditorNode::EditorNode() {
 EditorNode::EditorNode() {
 
 
-	Input::get_singleton()->set_use_accumulated_input(true);
+	InputFilter::get_singleton()->set_use_accumulated_input(true);
 	Resource::_get_local_scene_func = _resource_get_edited_scene;
 	Resource::_get_local_scene_func = _resource_get_edited_scene;
 
 
 	VisualServer::get_singleton()->set_debug_generate_wireframes(true);
 	VisualServer::get_singleton()->set_debug_generate_wireframes(true);
@@ -5488,7 +5488,7 @@ EditorNode::EditorNode() {
 	ResourceLoader::clear_translation_remaps(); //no remaps using during editor
 	ResourceLoader::clear_translation_remaps(); //no remaps using during editor
 	ResourceLoader::clear_path_remaps();
 	ResourceLoader::clear_path_remaps();
 
 
-	Input *id = Input::get_singleton();
+	InputFilter *id = InputFilter::get_singleton();
 
 
 	if (id) {
 	if (id) {
 
 
@@ -5499,7 +5499,7 @@ EditorNode::EditorNode() {
 			}
 			}
 		}
 		}
 
 
-		if (!found_touchscreen && Input::get_singleton()) {
+		if (!found_touchscreen && InputFilter::get_singleton()) {
 			//only if no touchscreen ui hint, set emulation
 			//only if no touchscreen ui hint, set emulation
 			id->set_emulate_touch_from_mouse(false); //just disable just in case
 			id->set_emulate_touch_from_mouse(false); //just disable just in case
 		}
 		}

+ 1 - 1
editor/editor_plugin_settings.cpp

@@ -40,7 +40,7 @@
 
 
 void EditorPluginSettings::_notification(int p_what) {
 void EditorPluginSettings::_notification(int p_what) {
 
 
-	if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) {
+	if (p_what == NOTIFICATION_WM_FOCUS_IN) {
 		update_plugins();
 		update_plugins();
 	} else if (p_what == Node::NOTIFICATION_READY) {
 	} else if (p_what == Node::NOTIFICATION_READY) {
 		plugin_config_dialog->connect_compat("plugin_ready", EditorNode::get_singleton(), "_on_plugin_ready");
 		plugin_config_dialog->connect_compat("plugin_ready", EditorNode::get_singleton(), "_on_plugin_ready");

+ 11 - 15
editor/editor_spin_slider.cpp

@@ -29,7 +29,8 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "editor_spin_slider.h"
 #include "editor_spin_slider.h"
-#include "core/input/input.h"
+
+#include "core/input/input_filter.h"
 #include "core/math/expression.h"
 #include "core/math/expression.h"
 #include "editor_node.h"
 #include "editor_node.h"
 #include "editor_scale.h"
 #include "editor_scale.h"
@@ -67,7 +68,7 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
 					grabbing_spinner_dist_cache = 0;
 					grabbing_spinner_dist_cache = 0;
 					pre_grab_value = get_value();
 					pre_grab_value = get_value();
 					grabbing_spinner = false;
 					grabbing_spinner = false;
-					grabbing_spinner_mouse_pos = Input::get_singleton()->get_mouse_position();
+					grabbing_spinner_mouse_pos = InputFilter::get_singleton()->get_mouse_position();
 				}
 				}
 			} else {
 			} else {
 
 
@@ -75,8 +76,8 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
 
 
 					if (grabbing_spinner) {
 					if (grabbing_spinner) {
 
 
-						Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
-						Input::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos);
+						InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
+						InputFilter::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos);
 						update();
 						update();
 					} else {
 					} else {
 						_focus_entered();
 						_focus_entered();
@@ -105,7 +106,7 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
 			grabbing_spinner_dist_cache += diff_x;
 			grabbing_spinner_dist_cache += diff_x;
 
 
 			if (!grabbing_spinner && ABS(grabbing_spinner_dist_cache) > 4 * EDSCALE) {
 			if (!grabbing_spinner && ABS(grabbing_spinner_dist_cache) > 4 * EDSCALE) {
-				Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
+				InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED);
 				grabbing_spinner = true;
 				grabbing_spinner = true;
 			}
 			}
 
 
@@ -176,11 +177,11 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
 
 
 void EditorSpinSlider::_notification(int p_what) {
 void EditorSpinSlider::_notification(int p_what) {
 
 
-	if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_OUT ||
-			p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN ||
+	if (p_what == NOTIFICATION_WM_FOCUS_OUT ||
+			p_what == NOTIFICATION_WM_FOCUS_IN ||
 			p_what == NOTIFICATION_EXIT_TREE) {
 			p_what == NOTIFICATION_EXIT_TREE) {
 		if (grabbing_spinner) {
 		if (grabbing_spinner) {
-			Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+			InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
 			grabbing_spinner = false;
 			grabbing_spinner = false;
 			grabbing_spinner_attempt = false;
 			grabbing_spinner_attempt = false;
 		}
 		}
@@ -297,7 +298,7 @@ void EditorSpinSlider::_notification(int p_what) {
 				grabber->set_position(get_global_position() + grabber_rect.position + grabber_rect.size * 0.5 - grabber->get_size() * 0.5);
 				grabber->set_position(get_global_position() + grabber_rect.position + grabber_rect.size * 0.5 - grabber->get_size() * 0.5);
 
 
 				if (mousewheel_over_grabber) {
 				if (mousewheel_over_grabber) {
-					Input::get_singleton()->warp_mouse_position(grabber->get_position() + grabber_rect.size);
+					InputFilter::get_singleton()->warp_mouse_position(grabber->get_position() + grabber_rect.size);
 				}
 				}
 
 
 				grabber_range = width;
 				grabber_range = width;
@@ -316,12 +317,7 @@ void EditorSpinSlider::_notification(int p_what) {
 		update();
 		update();
 	}
 	}
 	if (p_what == NOTIFICATION_FOCUS_ENTER) {
 	if (p_what == NOTIFICATION_FOCUS_ENTER) {
-		/* Sorry, I don't like this, it makes navigating the different fields with arrows more difficult.
-		 * Just press enter to edit.
-		 * if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && !value_input_just_closed) {
-			_focus_entered();
-		}*/
-		if ((Input::get_singleton()->is_action_pressed("ui_focus_next") || Input::get_singleton()->is_action_pressed("ui_focus_prev")) && !value_input_just_closed) {
+		if ((InputFilter::get_singleton()->is_action_pressed("ui_focus_next") || InputFilter::get_singleton()->is_action_pressed("ui_focus_prev")) && !value_input_just_closed) {
 			_focus_entered();
 			_focus_entered();
 		}
 		}
 		value_input_just_closed = false;
 		value_input_just_closed = false;

+ 2 - 2
editor/export_template_manager.cpp

@@ -30,7 +30,7 @@
 
 
 #include "export_template_manager.h"
 #include "export_template_manager.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/json.h"
 #include "core/io/json.h"
 #include "core/io/zip_io.h"
 #include "core/io/zip_io.h"
 #include "core/os/dir_access.h"
 #include "core/os/dir_access.h"
@@ -446,7 +446,7 @@ void ExportTemplateManager::_http_download_templates_completed(int p_status, int
 
 
 void ExportTemplateManager::_begin_template_download(const String &p_url) {
 void ExportTemplateManager::_begin_template_download(const String &p_url) {
 
 
-	if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 		OS::get_singleton()->shell_open(p_url);
 		OS::get_singleton()->shell_open(p_url);
 		return;
 		return;
 	}
 	}

+ 1 - 1
editor/plugins/animation_blend_space_2d_editor.cpp

@@ -30,7 +30,7 @@
 
 
 #include "animation_blend_space_2d_editor.h"
 #include "animation_blend_space_2d_editor.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/math/delaunay.h"
 #include "core/math/delaunay.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"

+ 1 - 1
editor/plugins/animation_blend_tree_editor_plugin.cpp

@@ -30,7 +30,7 @@
 
 
 #include "animation_blend_tree_editor_plugin.h"
 #include "animation_blend_tree_editor_plugin.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"

+ 2 - 2
editor/plugins/animation_player_editor_plugin.cpp

@@ -30,7 +30,7 @@
 
 
 #include "animation_player_editor_plugin.h"
 #include "animation_player_editor_plugin.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_saver.h"
 #include "core/io/resource_saver.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
@@ -488,7 +488,7 @@ double AnimationPlayerEditor::_get_editor_step() const {
 		ERR_FAIL_COND_V(!anim.is_valid(), 0.0);
 		ERR_FAIL_COND_V(!anim.is_valid(), 0.0);
 
 
 		// Use more precise snapping when holding Shift
 		// Use more precise snapping when holding Shift
-		return Input::get_singleton()->is_key_pressed(KEY_SHIFT) ? anim->get_step() * 0.25 : anim->get_step();
+		return InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT) ? anim->get_step() * 0.25 : anim->get_step();
 	}
 	}
 
 
 	return 0.0;
 	return 0.0;

+ 1 - 1
editor/plugins/animation_state_machine_editor.cpp

@@ -30,7 +30,7 @@
 
 
 #include "animation_state_machine_editor.h"
 #include "animation_state_machine_editor.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/math/delaunay.h"
 #include "core/math/delaunay.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"

+ 1 - 1
editor/plugins/animation_tree_editor_plugin.cpp

@@ -34,7 +34,7 @@
 #include "animation_blend_space_2d_editor.h"
 #include "animation_blend_space_2d_editor.h"
 #include "animation_blend_tree_editor_plugin.h"
 #include "animation_blend_tree_editor_plugin.h"
 #include "animation_state_machine_editor.h"
 #include "animation_state_machine_editor.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/math/delaunay.h"
 #include "core/math/delaunay.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"

+ 1 - 1
editor/plugins/asset_library_editor_plugin.cpp

@@ -30,7 +30,7 @@
 
 
 #include "asset_library_editor_plugin.h"
 #include "asset_library_editor_plugin.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/json.h"
 #include "core/io/json.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/version.h"
 #include "core/version.h"

+ 14 - 14
editor/plugins/canvas_item_editor_plugin.cpp

@@ -30,7 +30,7 @@
 
 
 #include "canvas_item_editor_plugin.h"
 #include "canvas_item_editor_plugin.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/print_string.h"
 #include "core/print_string.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
@@ -334,7 +334,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig
 	snap_target[0] = SNAP_TARGET_NONE;
 	snap_target[0] = SNAP_TARGET_NONE;
 	snap_target[1] = SNAP_TARGET_NONE;
 	snap_target[1] = SNAP_TARGET_NONE;
 
 
-	bool is_snap_active = smart_snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+	bool is_snap_active = smart_snap_active ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
 
 
 	// Smart snap using the canvas position
 	// Smart snap using the canvas position
 	Vector2 output = p_target;
 	Vector2 output = p_target;
@@ -462,7 +462,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig
 }
 }
 
 
 float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
 float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
-	if (((smart_snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) {
+	if (((smart_snap_active || snap_rotation) ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) {
 		if (snap_relative) {
 		if (snap_relative) {
 			return Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step);
 			return Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step);
 		} else {
 		} else {
@@ -1284,7 +1284,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
 			// Pan the viewport
 			// Pan the viewport
 			Point2i relative;
 			Point2i relative;
 			if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) {
 			if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) {
-				relative = Input::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect());
+				relative = InputFilter::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect());
 			} else {
 			} else {
 				relative = m->get_relative();
 				relative = m->get_relative();
 			}
 			}
@@ -1912,7 +1912,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
 			Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform;
 			Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform;
 
 
 			bool uniform = m->get_shift();
 			bool uniform = m->get_shift();
-			bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+			bool is_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
 
 
 			Point2 drag_from_local = simple_xform.xform(drag_from);
 			Point2 drag_from_local = simple_xform.xform(drag_from);
 			Point2 drag_to_local = simple_xform.xform(drag_to);
 			Point2 drag_to_local = simple_xform.xform(drag_to);
@@ -2207,10 +2207,10 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
 	if (k.is_valid() && !k->is_pressed() && drag_type == DRAG_KEY_MOVE && tool == TOOL_SELECT &&
 	if (k.is_valid() && !k->is_pressed() && drag_type == DRAG_KEY_MOVE && tool == TOOL_SELECT &&
 			(k->get_keycode() == KEY_UP || k->get_keycode() == KEY_DOWN || k->get_keycode() == KEY_LEFT || k->get_keycode() == KEY_RIGHT)) {
 			(k->get_keycode() == KEY_UP || k->get_keycode() == KEY_DOWN || k->get_keycode() == KEY_LEFT || k->get_keycode() == KEY_RIGHT)) {
 		// Confirm canvas items move by arrow keys
 		// Confirm canvas items move by arrow keys
-		if ((!Input::get_singleton()->is_key_pressed(KEY_UP)) &&
-				(!Input::get_singleton()->is_key_pressed(KEY_DOWN)) &&
-				(!Input::get_singleton()->is_key_pressed(KEY_LEFT)) &&
-				(!Input::get_singleton()->is_key_pressed(KEY_RIGHT))) {
+		if ((!InputFilter::get_singleton()->is_key_pressed(KEY_UP)) &&
+				(!InputFilter::get_singleton()->is_key_pressed(KEY_DOWN)) &&
+				(!InputFilter::get_singleton()->is_key_pressed(KEY_LEFT)) &&
+				(!InputFilter::get_singleton()->is_key_pressed(KEY_RIGHT))) {
 			_commit_canvas_item_state(drag_selection, TTR("Move CanvasItem"), true);
 			_commit_canvas_item_state(drag_selection, TTR("Move CanvasItem"), true);
 			drag_type = DRAG_NONE;
 			drag_type = DRAG_NONE;
 		}
 		}
@@ -3297,8 +3297,8 @@ void CanvasItemEditor::_draw_selection() {
 			}
 			}
 
 
 			// Draw the move handles
 			// Draw the move handles
-			bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
-			bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT);
+			bool is_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+			bool is_alt = InputFilter::get_singleton()->is_key_pressed(KEY_ALT);
 			if (tool == TOOL_MOVE && show_transformation_gizmos) {
 			if (tool == TOOL_MOVE && show_transformation_gizmos) {
 				if (_is_node_movable(canvas_item)) {
 				if (_is_node_movable(canvas_item)) {
 					Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized();
 					Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized();
@@ -3334,7 +3334,7 @@ void CanvasItemEditor::_draw_selection() {
 					Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
 					Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
 
 
 					Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE);
 					Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE);
-					bool uniform = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
+					bool uniform = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
 					Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom;
 					Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom;
 
 
 					if (drag_type == DRAG_SCALE_X) {
 					if (drag_type == DRAG_SCALE_X) {
@@ -6191,8 +6191,8 @@ bool CanvasItemEditorViewport::_only_packed_scenes_selected() const {
 }
 }
 
 
 void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p_data) {
 void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p_data) {
-	bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
-	bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT);
+	bool is_shift = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
+	bool is_alt = InputFilter::get_singleton()->is_key_pressed(KEY_ALT);
 
 
 	selected_files.clear();
 	selected_files.clear();
 	Dictionary d = p_data;
 	Dictionary d = p_data;

+ 2 - 2
editor/plugins/collision_polygon_editor_plugin.cpp

@@ -31,7 +31,7 @@
 #include "collision_polygon_editor_plugin.h"
 #include "collision_polygon_editor_plugin.h"
 
 
 #include "canvas_item_editor_plugin.h"
 #include "canvas_item_editor_plugin.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/file_access.h"
 #include "core/os/file_access.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "editor/editor_settings.h"
 #include "editor/editor_settings.h"
@@ -342,7 +342,7 @@ bool Polygon3DEditor::forward_spatial_gui_input(Camera *p_camera, const Ref<Inpu
 
 
 			Vector2 cpoint(spoint.x, spoint.y);
 			Vector2 cpoint(spoint.x, spoint.y);
 
 
-			if (snap_ignore && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+			if (snap_ignore && !InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
 				snap_ignore = false;
 				snap_ignore = false;
 			}
 			}
 
 

+ 2 - 2
editor/plugins/curve_editor_plugin.cpp

@@ -32,7 +32,7 @@
 
 
 #include "canvas_item_editor_plugin.h"
 #include "canvas_item_editor_plugin.h"
 #include "core/core_string_names.h"
 #include "core/core_string_names.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "editor/editor_scale.h"
 #include "editor/editor_scale.h"
 
 
@@ -210,7 +210,7 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
 					else
 					else
 						tangent = 9999 * (dir.y >= 0 ? 1 : -1);
 						tangent = 9999 * (dir.y >= 0 ? 1 : -1);
 
 
-					bool link = !Input::get_singleton()->is_key_pressed(KEY_SHIFT);
+					bool link = !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
 
 
 					if (_selected_tangent == TANGENT_LEFT) {
 					if (_selected_tangent == TANGENT_LEFT) {
 						curve.set_point_left_tangent(_selected_point, tangent);
 						curve.set_point_left_tangent(_selected_point, tangent);

+ 2 - 2
editor/plugins/polygon_2d_editor_plugin.cpp

@@ -31,7 +31,7 @@
 #include "polygon_2d_editor_plugin.h"
 #include "polygon_2d_editor_plugin.h"
 
 
 #include "canvas_item_editor_plugin.h"
 #include "canvas_item_editor_plugin.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/file_access.h"
 #include "core/os/file_access.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "editor/editor_scale.h"
 #include "editor/editor_scale.h"
@@ -810,7 +810,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
 
 
 	if (mm.is_valid()) {
 	if (mm.is_valid()) {
 
 
-		if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
+		if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)) {
 
 
 			Vector2 drag(mm->get_relative().x, mm->get_relative().y);
 			Vector2 drag(mm->get_relative().x, mm->get_relative().y);
 			uv_hscroll->set_value(uv_hscroll->get_value() - drag.x);
 			uv_hscroll->set_value(uv_hscroll->get_value() - drag.x);

+ 3 - 3
editor/plugins/script_editor_plugin.cpp

@@ -30,7 +30,7 @@
 
 
 #include "script_editor_plugin.h"
 #include "script_editor_plugin.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/os/file_access.h"
 #include "core/os/file_access.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
@@ -1425,7 +1425,7 @@ void ScriptEditor::_notification(int p_what) {
 			editor->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
 			editor->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
 		} break;
 		} break;
 
 
-		case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
+		case NOTIFICATION_WM_FOCUS_IN: {
 
 
 			_test_script_times_on_disk();
 			_test_script_times_on_disk();
 			_update_modified_scripts_for_external_editor();
 			_update_modified_scripts_for_external_editor();
@@ -1551,7 +1551,7 @@ void ScriptEditor::_help_overview_selected(int p_idx) {
 
 
 void ScriptEditor::_script_selected(int p_idx) {
 void ScriptEditor::_script_selected(int p_idx) {
 
 
-	grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing
+	grab_focus_block = !InputFilter::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing
 
 
 	_go_to_tab(script_list->get_item_metadata(p_idx));
 	_go_to_tab(script_list->get_item_metadata(p_idx));
 	grab_focus_block = false;
 	grab_focus_block = false;

+ 1 - 1
editor/plugins/shader_editor_plugin.cpp

@@ -352,7 +352,7 @@ void ShaderEditor::_menu_option(int p_option) {
 
 
 void ShaderEditor::_notification(int p_what) {
 void ShaderEditor::_notification(int p_what) {
 
 
-	if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) {
+	if (p_what == NOTIFICATION_WM_FOCUS_IN) {
 		_check_for_external_edit();
 		_check_for_external_edit();
 	}
 	}
 }
 }

+ 12 - 12
editor/plugins/spatial_editor_plugin.cpp

@@ -30,7 +30,7 @@
 
 
 #include "spatial_editor_plugin.h"
 #include "spatial_editor_plugin.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/math/camera_matrix.h"
 #include "core/math/camera_matrix.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/print_string.h"
 #include "core/print_string.h"
@@ -298,10 +298,10 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) {
 			float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
 			float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
 
 
 			//determine if being manipulated
 			//determine if being manipulated
-			bool manipulated = Input::get_singleton()->get_mouse_button_mask() & (2 | 4);
-			manipulated |= Input::get_singleton()->is_key_pressed(KEY_SHIFT);
-			manipulated |= Input::get_singleton()->is_key_pressed(KEY_ALT);
-			manipulated |= Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+			bool manipulated = InputFilter::get_singleton()->get_mouse_button_mask() & (2 | 4);
+			manipulated |= InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
+			manipulated |= InputFilter::get_singleton()->is_key_pressed(KEY_ALT);
+			manipulated |= InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
 
 
 			float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
 			float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
 			float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
 			float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
@@ -2260,7 +2260,7 @@ void SpatialEditorViewport::scale_freelook_speed(real_t scale) {
 Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const {
 Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const {
 	Point2i relative;
 	Point2i relative;
 	if (bool(EDITOR_DEF("editors/3d/navigation/warped_mouse_panning", false))) {
 	if (bool(EDITOR_DEF("editors/3d/navigation/warped_mouse_panning", false))) {
-		relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect());
+		relative = InputFilter::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect());
 	} else {
 	} else {
 		relative = p_ev_mouse_motion->get_relative();
 		relative = p_ev_mouse_motion->get_relative();
 	}
 	}
@@ -2276,7 +2276,7 @@ static bool is_shortcut_pressed(const String &p_path) {
 	if (k == NULL) {
 	if (k == NULL) {
 		return false;
 		return false;
 	}
 	}
-	const Input &input = *Input::get_singleton();
+	const InputFilter &input = *InputFilter::get_singleton();
 	int keycode = k->get_keycode();
 	int keycode = k->get_keycode();
 	return input.is_key_pressed(keycode);
 	return input.is_key_pressed(keycode);
 }
 }
@@ -3771,7 +3771,7 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p
 	if (!can_drop_data_fw(p_point, p_data, p_from))
 	if (!can_drop_data_fw(p_point, p_data, p_from))
 		return;
 		return;
 
 
-	bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
+	bool is_shift = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
 
 
 	selected_files.clear();
 	selected_files.clear();
 	Dictionary d = p_data;
 	Dictionary d = p_data;
@@ -5721,7 +5721,7 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
 	if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
 	if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
 		return;
 		return;
 
 
-	snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+	snap_key_enabled = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
 }
 }
 void SpatialEditor::_notification(int p_what) {
 void SpatialEditor::_notification(int p_what) {
 
 
@@ -6381,7 +6381,7 @@ Vector3 SpatialEditor::snap_point(Vector3 p_target, Vector3 p_start) const {
 
 
 float SpatialEditor::get_translate_snap() const {
 float SpatialEditor::get_translate_snap() const {
 	float snap_value;
 	float snap_value;
-	if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 		snap_value = snap_translate->get_text().to_double() / 10.0;
 		snap_value = snap_translate->get_text().to_double() / 10.0;
 	} else {
 	} else {
 		snap_value = snap_translate->get_text().to_double();
 		snap_value = snap_translate->get_text().to_double();
@@ -6392,7 +6392,7 @@ float SpatialEditor::get_translate_snap() const {
 
 
 float SpatialEditor::get_rotate_snap() const {
 float SpatialEditor::get_rotate_snap() const {
 	float snap_value;
 	float snap_value;
-	if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 		snap_value = snap_rotate->get_text().to_double() / 3.0;
 		snap_value = snap_rotate->get_text().to_double() / 3.0;
 	} else {
 	} else {
 		snap_value = snap_rotate->get_text().to_double();
 		snap_value = snap_rotate->get_text().to_double();
@@ -6403,7 +6403,7 @@ float SpatialEditor::get_rotate_snap() const {
 
 
 float SpatialEditor::get_scale_snap() const {
 float SpatialEditor::get_scale_snap() const {
 	float snap_value;
 	float snap_value;
-	if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 		snap_value = snap_scale->get_text().to_double() / 2.0;
 		snap_value = snap_scale->get_text().to_double() / 2.0;
 	} else {
 	} else {
 		snap_value = snap_scale->get_text().to_double();
 		snap_value = snap_scale->get_text().to_double();

+ 4 - 4
editor/plugins/texture_region_editor_plugin.cpp

@@ -31,7 +31,7 @@
 #include "texture_region_editor_plugin.h"
 #include "texture_region_editor_plugin.h"
 
 
 #include "core/core_string_names.h"
 #include "core/core_string_names.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "editor/editor_scale.h"
 #include "editor/editor_scale.h"
 #include "scene/gui/check_box.h"
 #include "scene/gui/check_box.h"
@@ -307,7 +307,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
 					for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) {
 					for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) {
 						if (E->get().has_point(point)) {
 						if (E->get().has_point(point)) {
 							rect = E->get();
 							rect = E->get();
-							if (Input::get_singleton()->is_key_pressed(KEY_CONTROL) && !(Input::get_singleton()->is_key_pressed(KEY_SHIFT | KEY_ALT))) {
+							if (InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL) && !(InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT | KEY_ALT))) {
 								Rect2 r;
 								Rect2 r;
 								if (node_sprite)
 								if (node_sprite)
 									r = node_sprite->get_region_rect();
 									r = node_sprite->get_region_rect();
@@ -449,7 +449,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
 
 
 	if (mm.is_valid()) {
 	if (mm.is_valid()) {
 
 
-		if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
+		if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)) {
 
 
 			Vector2 dragged(mm->get_relative().x / draw_zoom, mm->get_relative().y / draw_zoom);
 			Vector2 dragged(mm->get_relative().x / draw_zoom, mm->get_relative().y / draw_zoom);
 			hscroll->set_value(hscroll->get_value() - dragged.x);
 			hscroll->set_value(hscroll->get_value() - dragged.x);
@@ -756,7 +756,7 @@ void TextureRegionEditor::_notification(int p_what) {
 				_update_autoslice();
 				_update_autoslice();
 			}
 			}
 		} break;
 		} break;
-		case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
+		case NOTIFICATION_WM_FOCUS_IN: {
 			// This happens when the user leaves the Editor and returns,
 			// This happens when the user leaves the Editor and returns,
 			// they could have changed the textures, so the cache is cleared.
 			// they could have changed the textures, so the cache is cleared.
 			cache_map.clear();
 			cache_map.clear();

+ 3 - 3
editor/plugins/tile_map_editor_plugin.cpp

@@ -31,7 +31,7 @@
 #include "tile_map_editor_plugin.h"
 #include "tile_map_editor_plugin.h"
 
 
 #include "canvas_item_editor_plugin.h"
 #include "canvas_item_editor_plugin.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/math/math_funcs.h"
 #include "core/math/math_funcs.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "editor/editor_scale.h"
 #include "editor/editor_scale.h"
@@ -984,7 +984,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 			if (mb->is_pressed()) {
 			if (mb->is_pressed()) {
 
 
-				if (Input::get_singleton()->is_key_pressed(KEY_SPACE))
+				if (InputFilter::get_singleton()->is_key_pressed(KEY_SPACE))
 					return false; // Drag.
 					return false; // Drag.
 
 
 				if (tool == TOOL_NONE) {
 				if (tool == TOOL_NONE) {
@@ -1365,7 +1365,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
 
 
 			return true;
 			return true;
 		}
 		}
-		if (tool == TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+		if (tool == TOOL_PICKING && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
 
 
 			_pick_tile(over_tile);
 			_pick_tile(over_tile);
 
 

+ 3 - 3
editor/plugins/tile_set_editor_plugin.cpp

@@ -30,7 +30,7 @@
 
 
 #include "tile_set_editor_plugin.h"
 #include "tile_set_editor_plugin.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "editor/editor_scale.h"
 #include "editor/editor_scale.h"
 #include "editor/plugins/canvas_item_editor_plugin.h"
 #include "editor/plugins/canvas_item_editor_plugin.h"
@@ -1113,7 +1113,7 @@ void TileSetEditor::_on_workspace_draw() {
 
 
 void TileSetEditor::_on_workspace_process() {
 void TileSetEditor::_on_workspace_process() {
 
 
-	if (Input::get_singleton()->is_key_pressed(KEY_ALT) || tools[VISIBLE_INFO]->is_pressed()) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_ALT) || tools[VISIBLE_INFO]->is_pressed()) {
 		if (!tile_names_visible) {
 		if (!tile_names_visible) {
 			tile_names_visible = true;
 			tile_names_visible = true;
 			workspace_overlay->update();
 			workspace_overlay->update();
@@ -1395,7 +1395,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
 							if ((mb->get_button_index() == BUTTON_RIGHT || mb->get_button_index() == BUTTON_LEFT) && current_tile_region.has_point(mb->get_position())) {
 							if ((mb->get_button_index() == BUTTON_RIGHT || mb->get_button_index() == BUTTON_LEFT) && current_tile_region.has_point(mb->get_position())) {
 								dragging = true;
 								dragging = true;
 								erasing = (mb->get_button_index() == BUTTON_RIGHT);
 								erasing = (mb->get_button_index() == BUTTON_RIGHT);
-								alternative = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
+								alternative = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
 								Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
 								Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
 								Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
 								Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
 								pos = mb->get_position() - (pos + current_tile_region.position);
 								pos = mb->get_position() - (pos + current_tile_region.position);

+ 3 - 3
editor/plugins/visual_shader_editor_plugin.cpp

@@ -30,7 +30,7 @@
 
 
 #include "visual_shader_editor_plugin.h"
 #include "visual_shader_editor_plugin.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/math/math_defs.h"
 #include "core/math/math_defs.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
@@ -1624,7 +1624,7 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
 			popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.empty());
 			popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.empty());
 			popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.empty());
 			popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.empty());
 			menu_point = graph->get_local_mouse_position();
 			menu_point = graph->get_local_mouse_position();
-			Point2 gpos = Input::get_singleton()->get_mouse_position();
+			Point2 gpos = InputFilter::get_singleton()->get_mouse_position();
 			popup_menu->set_position(gpos);
 			popup_menu->set_position(gpos);
 			popup_menu->popup();
 			popup_menu->popup();
 		}
 		}
@@ -1637,7 +1637,7 @@ void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos) {
 		saved_node_pos_dirty = true;
 		saved_node_pos_dirty = true;
 		saved_node_pos = graph->get_local_mouse_position();
 		saved_node_pos = graph->get_local_mouse_position();
 
 
-		Point2 gpos = Input::get_singleton()->get_mouse_position();
+		Point2 gpos = InputFilter::get_singleton()->get_mouse_position();
 		members_dialog->popup();
 		members_dialog->popup();
 		members_dialog->set_position(gpos);
 		members_dialog->set_position(gpos);
 	} else {
 	} else {

+ 4 - 3
editor/project_manager.cpp

@@ -51,6 +51,7 @@
 #include "scene/gui/separator.h"
 #include "scene/gui/separator.h"
 #include "scene/gui/texture_rect.h"
 #include "scene/gui/texture_rect.h"
 #include "scene/gui/tool_button.h"
 #include "scene/gui/tool_button.h"
+#include "scene/main/window.h"
 #include "servers/display_server.h"
 #include "servers/display_server.h"
 
 
 static inline String get_project_key_from_path(const String &dir) {
 static inline String get_project_key_from_path(const String &dir) {
@@ -657,7 +658,7 @@ private:
 
 
 	void _notification(int p_what) {
 	void _notification(int p_what) {
 
 
-		if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST)
+		if (p_what == NOTIFICATION_WM_CLOSE_REQUEST)
 			_remove_created_folder();
 			_remove_created_folder();
 	}
 	}
 
 
@@ -1850,7 +1851,7 @@ void ProjectManager::_notification(int p_what) {
 
 
 			set_process_unhandled_input(is_visible_in_tree());
 			set_process_unhandled_input(is_visible_in_tree());
 		} break;
 		} break;
-		case NOTIFICATION_WM_QUIT_REQUEST: {
+		case NOTIFICATION_WM_CLOSE_REQUEST: {
 
 
 			_dim_window();
 			_dim_window();
 		} break;
 		} break;
@@ -2694,7 +2695,7 @@ ProjectManager::ProjectManager() {
 		_scan_begin(EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path"));
 		_scan_begin(EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path"));
 	}
 	}
 
 
-	SceneTree::get_singleton()->connect("files_dropped", callable_mp(this, &ProjectManager::_files_dropped));
+	SceneTree::get_singleton()->get_root()->connect("files_dropped", callable_mp(this, &ProjectManager::_files_dropped));
 	SceneTree::get_singleton()->connect("global_menu_action", callable_mp(this, &ProjectManager::_global_menu_action));
 	SceneTree::get_singleton()->connect("global_menu_action", callable_mp(this, &ProjectManager::_global_menu_action));
 
 
 	run_error_diag = memnew(AcceptDialog);
 	run_error_diag = memnew(AcceptDialog);

+ 3 - 3
editor/property_editor.cpp

@@ -31,7 +31,7 @@
 #include "property_editor.h"
 #include "property_editor.h"
 
 
 #include "core/class_db.h"
 #include "core/class_db.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/image_loader.h"
 #include "core/io/image_loader.h"
 #include "core/io/marshalls.h"
 #include "core/io/marshalls.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
@@ -108,7 +108,7 @@ void CustomPropertyEditor::_notification(int p_what) {
 		RID ci = get_canvas_item();
 		RID ci = get_canvas_item();
 		get_stylebox("panel", "PopupMenu")->draw(ci, Rect2(Point2(), get_size()));
 		get_stylebox("panel", "PopupMenu")->draw(ci, Rect2(Point2(), get_size()));
 	}
 	}
-	if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) {
+	if (p_what == NOTIFICATION_WM_CLOSE_REQUEST) {
 		hide();
 		hide();
 	}
 	}
 }
 }
@@ -1743,7 +1743,7 @@ real_t CustomPropertyEditor::_parse_real_expression(String text) {
 
 
 void CustomPropertyEditor::_emit_changed_whole_or_field() {
 void CustomPropertyEditor::_emit_changed_whole_or_field() {
 
 
-	if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+	if (!InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 		emit_signal("variant_changed");
 		emit_signal("variant_changed");
 	} else {
 	} else {
 		emit_signal("variant_field_changed", field_names[focused_value_editor]);
 		emit_signal("variant_field_changed", field_names[focused_value_editor]);

+ 3 - 3
editor/scene_tree_dock.cpp

@@ -30,7 +30,7 @@
 
 
 #include "scene_tree_dock.h"
 #include "scene_tree_dock.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/resource_saver.h"
 #include "core/io/resource_saver.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
@@ -1033,7 +1033,7 @@ void SceneTreeDock::_node_collapsed(Object *p_obj) {
 	if (!ti)
 	if (!ti)
 		return;
 		return;
 
 
-	if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 		_set_collapsed_recursive(ti, ti->is_collapsed());
 		_set_collapsed_recursive(ti, ti->is_collapsed());
 	}
 	}
 }
 }
@@ -2348,7 +2348,7 @@ void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) {
 	int to_pos = -1;
 	int to_pos = -1;
 
 
 	_normalize_drop(to_node, to_pos, p_type);
 	_normalize_drop(to_node, to_pos, p_type);
-	_do_reparent(to_node, to_pos, nodes, !Input::get_singleton()->is_key_pressed(KEY_SHIFT));
+	_do_reparent(to_node, to_pos, nodes, !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT));
 }
 }
 
 
 void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) {
 void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) {

+ 5 - 6
main/main.cpp

@@ -32,7 +32,7 @@
 
 
 #include "core/crypto/crypto.h"
 #include "core/crypto/crypto.h"
 #include "core/debugger/engine_debugger.h"
 #include "core/debugger/engine_debugger.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/input/input_map.h"
 #include "core/input/input_map.h"
 #include "core/io/file_access_network.h"
 #include "core/io/file_access_network.h"
 #include "core/io/file_access_pack.h"
 #include "core/io/file_access_pack.h"
@@ -89,7 +89,7 @@
 // Initialized in setup()
 // Initialized in setup()
 static Engine *engine = NULL;
 static Engine *engine = NULL;
 static ProjectSettings *globals = NULL;
 static ProjectSettings *globals = NULL;
-static Input *input = NULL;
+static InputFilter *input = NULL;
 static InputMap *input_map = NULL;
 static InputMap *input_map = NULL;
 static TranslationServer *translation_server = NULL;
 static TranslationServer *translation_server = NULL;
 static Performance *performance = NULL;
 static Performance *performance = NULL;
@@ -1225,7 +1225,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
 
 
 	/* Initialize Input */
 	/* Initialize Input */
 
 
-	input = memnew(Input);
+	input = memnew(InputFilter);
 
 
 	/* Iniitalize Display Server */
 	/* Iniitalize Display Server */
 
 
@@ -1379,7 +1379,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
 	GLOBAL_DEF("application/config/windows_native_icon", String());
 	GLOBAL_DEF("application/config/windows_native_icon", String());
 	ProjectSettings::get_singleton()->set_custom_property_info("application/config/windows_native_icon", PropertyInfo(Variant::STRING, "application/config/windows_native_icon", PROPERTY_HINT_FILE, "*.ico"));
 	ProjectSettings::get_singleton()->set_custom_property_info("application/config/windows_native_icon", PropertyInfo(Variant::STRING, "application/config/windows_native_icon", PROPERTY_HINT_FILE, "*.ico"));
 
 
-	Input *id = Input::get_singleton();
+	InputFilter *id = InputFilter::get_singleton();
 	if (id) {
 	if (id) {
 		if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
 		if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
 
 
@@ -1414,7 +1414,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
 		Ref<Texture2D> cursor = ResourceLoader::load(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image"));
 		Ref<Texture2D> cursor = ResourceLoader::load(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image"));
 		if (cursor.is_valid()) {
 		if (cursor.is_valid()) {
 			Vector2 hotspot = ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image_hotspot");
 			Vector2 hotspot = ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image_hotspot");
-			Input::get_singleton()->set_custom_mouse_cursor(cursor, Input::CURSOR_ARROW, hotspot);
+			InputFilter::get_singleton()->set_custom_mouse_cursor(cursor, InputFilter::CURSOR_ARROW, hotspot);
 		}
 		}
 	}
 	}
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
@@ -2009,7 +2009,6 @@ bool Main::start() {
 		DisplayServer::get_singleton()->set_icon(icon);
 		DisplayServer::get_singleton()->set_icon(icon);
 	}
 	}
 
 
-	Input::get_singleton()->set_main_loop(main_loop);
 	OS::get_singleton()->set_main_loop(main_loop);
 	OS::get_singleton()->set_main_loop(main_loop);
 
 
 	return true;
 	return true;

+ 1 - 1
modules/arkit/arkit_interface.mm

@@ -28,7 +28,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 /*************************************************************************/
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "scene/resources/surface_tool.h"
 #include "scene/resources/surface_tool.h"
 #include "servers/visual/visual_server_globals.h"
 #include "servers/visual/visual_server_globals.h"

+ 6 - 6
modules/gdnative/arvr/arvr_interface_gdnative.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "arvr_interface_gdnative.h"
 #include "arvr_interface_gdnative.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "servers/arvr/arvr_positional_tracker.h"
 #include "servers/arvr/arvr_positional_tracker.h"
 #include "servers/visual/visual_server_globals.h"
 #include "servers/visual/visual_server_globals.h"
 
 
@@ -317,7 +317,7 @@ godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand,
 	ARVRServer *arvr_server = ARVRServer::get_singleton();
 	ARVRServer *arvr_server = ARVRServer::get_singleton();
 	ERR_FAIL_NULL_V(arvr_server, 0);
 	ERR_FAIL_NULL_V(arvr_server, 0);
 
 
-	Input *input = Input::get_singleton();
+	InputFilter *input = InputFilter::get_singleton();
 	ERR_FAIL_NULL_V(input, 0);
 	ERR_FAIL_NULL_V(input, 0);
 
 
 	ARVRPositionalTracker *new_tracker = memnew(ARVRPositionalTracker);
 	ARVRPositionalTracker *new_tracker = memnew(ARVRPositionalTracker);
@@ -356,7 +356,7 @@ void GDAPI godot_arvr_remove_controller(godot_int p_controller_id) {
 	ARVRServer *arvr_server = ARVRServer::get_singleton();
 	ARVRServer *arvr_server = ARVRServer::get_singleton();
 	ERR_FAIL_NULL(arvr_server);
 	ERR_FAIL_NULL(arvr_server);
 
 
-	Input *input = Input::get_singleton();
+	InputFilter *input = InputFilter::get_singleton();
 	ERR_FAIL_NULL(input);
 	ERR_FAIL_NULL(input);
 
 
 	ARVRPositionalTracker *remove_tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
 	ARVRPositionalTracker *remove_tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
@@ -394,7 +394,7 @@ void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int
 	ARVRServer *arvr_server = ARVRServer::get_singleton();
 	ARVRServer *arvr_server = ARVRServer::get_singleton();
 	ERR_FAIL_NULL(arvr_server);
 	ERR_FAIL_NULL(arvr_server);
 
 
-	Input *input = Input::get_singleton();
+	InputFilter *input = InputFilter::get_singleton();
 	ERR_FAIL_NULL(input);
 	ERR_FAIL_NULL(input);
 
 
 	ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
 	ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
@@ -410,14 +410,14 @@ void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p
 	ARVRServer *arvr_server = ARVRServer::get_singleton();
 	ARVRServer *arvr_server = ARVRServer::get_singleton();
 	ERR_FAIL_NULL(arvr_server);
 	ERR_FAIL_NULL(arvr_server);
 
 
-	Input *input = Input::get_singleton();
+	InputFilter *input = InputFilter::get_singleton();
 	ERR_FAIL_NULL(input);
 	ERR_FAIL_NULL(input);
 
 
 	ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
 	ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
 	if (tracker != NULL) {
 	if (tracker != NULL) {
 		int joyid = tracker->get_joy_id();
 		int joyid = tracker->get_joy_id();
 		if (joyid != -1) {
 		if (joyid != -1) {
-			Input::JoyAxis jx;
+			InputFilter::JoyAxis jx;
 			jx.min = p_can_be_negative ? -1 : 0;
 			jx.min = p_can_be_negative ? -1 : 0;
 			jx.value = p_value;
 			jx.value = p_value;
 			input->joy_axis(joyid, p_axis, jx);
 			input->joy_axis(joyid, p_axis, jx);

+ 2 - 2
modules/gdnative/nativescript/nativescript.cpp

@@ -1827,7 +1827,7 @@ void NativeReloadNode::_notification(int p_what) {
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 
 
 	switch (p_what) {
 	switch (p_what) {
-		case MainLoop::NOTIFICATION_WM_FOCUS_OUT: {
+		case NOTIFICATION_WM_FOCUS_OUT: {
 
 
 			if (unloaded)
 			if (unloaded)
 				break;
 				break;
@@ -1862,7 +1862,7 @@ void NativeReloadNode::_notification(int p_what) {
 
 
 		} break;
 		} break;
 
 
-		case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
+		case NOTIFICATION_WM_FOCUS_IN: {
 
 
 			if (!unloaded)
 			if (!unloaded)
 				break;
 				break;

+ 1 - 1
modules/gridmap/grid_map_editor_plugin.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "grid_map_editor_plugin.h"
 #include "grid_map_editor_plugin.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "editor/editor_scale.h"
 #include "editor/editor_scale.h"
 #include "editor/editor_settings.h"
 #include "editor/editor_settings.h"
 #include "editor/plugins/spatial_editor_plugin.h"
 #include "editor/plugins/spatial_editor_plugin.h"

+ 2 - 2
modules/mobile_vr/mobile_vr_interface.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "mobile_vr_interface.h"
 #include "mobile_vr_interface.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "servers/display_server.h"
 #include "servers/display_server.h"
 #include "servers/visual/visual_server_globals.h"
 #include "servers/visual/visual_server_globals.h"
@@ -118,7 +118,7 @@ void MobileVRInterface::set_position_from_sensors() {
 	float delta_time = (double)ticks_elapsed / 1000000.0;
 	float delta_time = (double)ticks_elapsed / 1000000.0;
 
 
 	// few things we need
 	// few things we need
-	Input *input = Input::get_singleton();
+	InputFilter *input = InputFilter::get_singleton();
 	Vector3 down(0.0, -1.0, 0.0); // Down is Y negative
 	Vector3 down(0.0, -1.0, 0.0); // Down is Y negative
 	Vector3 north(0.0, 0.0, 1.0); // North is Z positive
 	Vector3 north(0.0, 0.0, 1.0); // North is Z positive
 
 

+ 14 - 14
modules/visual_script/visual_script_editor.cpp

@@ -30,7 +30,7 @@
 
 
 #include "visual_script_editor.h"
 #include "visual_script_editor.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/object.h"
 #include "core/object.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/script_language.h"
 #include "core/script_language.h"
@@ -1057,9 +1057,9 @@ void VisualScriptEditor::_member_selected() {
 	if (ti->get_parent() == members->get_root()->get_children()) {
 	if (ti->get_parent() == members->get_root()->get_children()) {
 
 
 #ifdef OSX_ENABLED
 #ifdef OSX_ENABLED
-		bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_META);
+		bool held_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_META);
 #else
 #else
-		bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+		bool held_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
 #endif
 #endif
 		if (held_ctrl) {
 		if (held_ctrl) {
 			ERR_FAIL_COND(!script->has_function(selected));
 			ERR_FAIL_COND(!script->has_function(selected));
@@ -1360,7 +1360,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
 		}
 		}
 	} else if (ti->get_parent() == root->get_children()) {
 	} else if (ti->get_parent() == root->get_children()) {
 		selected = ti->get_text(0);
 		selected = ti->get_text(0);
-		function_name_edit->set_position(Input::get_singleton()->get_mouse_position() - Vector2(60, -10));
+		function_name_edit->set_position(InputFilter::get_singleton()->get_mouse_position() - Vector2(60, -10));
 		function_name_edit->popup();
 		function_name_edit->popup();
 		function_name_box->set_text(selected);
 		function_name_box->set_text(selected);
 		function_name_box->select_all();
 		function_name_box->select_all();
@@ -1722,7 +1722,7 @@ void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) {
 	Ref<InputEventMouseButton> key = p_event;
 	Ref<InputEventMouseButton> key = p_event;
 
 
 	if (key.is_valid() && !key->is_pressed()) {
 	if (key.is_valid() && !key->is_pressed()) {
-		mouse_up_position = Input::get_singleton()->get_mouse_position();
+		mouse_up_position = InputFilter::get_singleton()->get_mouse_position();
 	}
 	}
 }
 }
 
 
@@ -1732,7 +1732,7 @@ void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
 	if (key.is_valid() && key->is_pressed() && key->get_button_mask() == BUTTON_RIGHT) {
 	if (key.is_valid() && key->is_pressed() && key->get_button_mask() == BUTTON_RIGHT) {
 		saved_position = graph->get_local_mouse_position();
 		saved_position = graph->get_local_mouse_position();
 
 
-		Point2 gpos = Input::get_singleton()->get_mouse_position();
+		Point2 gpos = InputFilter::get_singleton()->get_mouse_position();
 		_generic_search(script->get_instance_base_type(), gpos);
 		_generic_search(script->get_instance_base_type(), gpos);
 	}
 	}
 }
 }
@@ -1986,9 +1986,9 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
 	if (String(d["type"]) == "visual_script_variable_drag") {
 	if (String(d["type"]) == "visual_script_variable_drag") {
 
 
 #ifdef OSX_ENABLED
 #ifdef OSX_ENABLED
-		bool use_set = Input::get_singleton()->is_key_pressed(KEY_META);
+		bool use_set = InputFilter::get_singleton()->is_key_pressed(KEY_META);
 #else
 #else
-		bool use_set = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+		bool use_set = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
 #endif
 #endif
 		Vector2 ofs = graph->get_scroll_ofs() + p_point;
 		Vector2 ofs = graph->get_scroll_ofs() + p_point;
 		if (graph->is_using_snap()) {
 		if (graph->is_using_snap()) {
@@ -2181,9 +2181,9 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
 		}
 		}
 
 
 #ifdef OSX_ENABLED
 #ifdef OSX_ENABLED
-		bool use_node = Input::get_singleton()->is_key_pressed(KEY_META);
+		bool use_node = InputFilter::get_singleton()->is_key_pressed(KEY_META);
 #else
 #else
-		bool use_node = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+		bool use_node = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
 #endif
 #endif
 
 
 		Array nodes = d["nodes"];
 		Array nodes = d["nodes"];
@@ -2245,7 +2245,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
 
 
 		Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
 		Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
 
 
-		if (!sn && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+		if (!sn && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 			EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop properties because script '%s' is not used in this scene.\nDrop holding 'Shift' to just copy the signature."), get_name()));
 			EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop properties because script '%s' is not used in this scene.\nDrop holding 'Shift' to just copy the signature."), get_name()));
 			return;
 			return;
 		}
 		}
@@ -2265,12 +2265,12 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
 
 
 		ofs /= EDSCALE;
 		ofs /= EDSCALE;
 #ifdef OSX_ENABLED
 #ifdef OSX_ENABLED
-		bool use_get = Input::get_singleton()->is_key_pressed(KEY_META);
+		bool use_get = InputFilter::get_singleton()->is_key_pressed(KEY_META);
 #else
 #else
-		bool use_get = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+		bool use_get = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
 #endif
 #endif
 
 
-		if (!node || Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+		if (!node || InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 
 
 			if (use_get)
 			if (use_get)
 				undo_redo->create_action(TTR("Add Getter Property"));
 				undo_redo->create_action(TTR("Add Getter Property"));

+ 5 - 5
modules/visual_script/visual_script_nodes.cpp

@@ -32,7 +32,7 @@
 
 
 #include "core/engine.h"
 #include "core/engine.h"
 #include "core/global_constants.h"
 #include "core/global_constants.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 #include "scene/main/node.h"
 #include "scene/main/node.h"
@@ -3870,16 +3870,16 @@ public:
 
 
 		switch (mode) {
 		switch (mode) {
 			case VisualScriptInputAction::MODE_PRESSED: {
 			case VisualScriptInputAction::MODE_PRESSED: {
-				*p_outputs[0] = Input::get_singleton()->is_action_pressed(action);
+				*p_outputs[0] = InputFilter::get_singleton()->is_action_pressed(action);
 			} break;
 			} break;
 			case VisualScriptInputAction::MODE_RELEASED: {
 			case VisualScriptInputAction::MODE_RELEASED: {
-				*p_outputs[0] = !Input::get_singleton()->is_action_pressed(action);
+				*p_outputs[0] = !InputFilter::get_singleton()->is_action_pressed(action);
 			} break;
 			} break;
 			case VisualScriptInputAction::MODE_JUST_PRESSED: {
 			case VisualScriptInputAction::MODE_JUST_PRESSED: {
-				*p_outputs[0] = Input::get_singleton()->is_action_just_pressed(action);
+				*p_outputs[0] = InputFilter::get_singleton()->is_action_just_pressed(action);
 			} break;
 			} break;
 			case VisualScriptInputAction::MODE_JUST_RELEASED: {
 			case VisualScriptInputAction::MODE_JUST_RELEASED: {
-				*p_outputs[0] = Input::get_singleton()->is_action_just_released(action);
+				*p_outputs[0] = InputFilter::get_singleton()->is_action_just_released(action);
 			} break;
 			} break;
 		}
 		}
 
 

+ 3 - 1
platform/android/java_godot_lib_jni.cpp

@@ -29,6 +29,7 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "java_godot_lib_jni.h"
 #include "java_godot_lib_jni.h"
+
 #include "java_godot_io_wrapper.h"
 #include "java_godot_io_wrapper.h"
 #include "java_godot_wrapper.h"
 #include "java_godot_wrapper.h"
 
 
@@ -37,7 +38,7 @@
 #include "api/java_class_wrapper.h"
 #include "api/java_class_wrapper.h"
 #include "audio_driver_jandroid.h"
 #include "audio_driver_jandroid.h"
 #include "core/engine.h"
 #include "core/engine.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 #include "dir_access_jandroid.h"
 #include "dir_access_jandroid.h"
 #include "file_access_android.h"
 #include "file_access_android.h"
@@ -48,6 +49,7 @@
 #include "os_android.h"
 #include "os_android.h"
 #include "string_android.h"
 #include "string_android.h"
 #include "thread_jandroid.h"
 #include "thread_jandroid.h"
+
 #include <unistd.h>
 #include <unistd.h>
 
 
 static JavaClassWrapper *java_class_wrapper = NULL;
 static JavaClassWrapper *java_class_wrapper = NULL;

+ 3 - 3
platform/android/os_android.cpp

@@ -306,14 +306,14 @@ void OS_Android::main_loop_end() {
 void OS_Android::main_loop_focusout() {
 void OS_Android::main_loop_focusout() {
 
 
 	if (main_loop)
 	if (main_loop)
-		main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+		main_loop->notification(NOTIFICATION_WM_FOCUS_OUT);
 	audio_driver_android.set_pause(true);
 	audio_driver_android.set_pause(true);
 }
 }
 
 
 void OS_Android::main_loop_focusin() {
 void OS_Android::main_loop_focusin() {
 
 
 	if (main_loop)
 	if (main_loop)
-		main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+		main_loop->notification(NOTIFICATION_WM_FOCUS_IN);
 	audio_driver_android.set_pause(false);
 	audio_driver_android.set_pause(false);
 }
 }
 
 
@@ -568,7 +568,7 @@ void OS_Android::init_video_mode(int p_video_width, int p_video_height) {
 void OS_Android::main_loop_request_go_back() {
 void OS_Android::main_loop_request_go_back() {
 
 
 	if (main_loop)
 	if (main_loop)
-		main_loop->notification(MainLoop::NOTIFICATION_WM_GO_BACK_REQUEST);
+		main_loop->notification(NOTIFICATION_WM_GO_BACK_REQUEST);
 }
 }
 
 
 void OS_Android::set_display_size(Size2 p_size) {
 void OS_Android::set_display_size(Size2 p_size) {

+ 1 - 1
platform/android/os_android.h

@@ -33,7 +33,7 @@
 
 
 #include "audio_driver_jandroid.h"
 #include "audio_driver_jandroid.h"
 #include "audio_driver_opensl.h"
 #include "audio_driver_opensl.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/main_loop.h"
 #include "core/os/main_loop.h"
 #include "drivers/unix/os_unix.h"
 #include "drivers/unix/os_unix.h"
 #include "servers/audio_server.h"
 #include "servers/audio_server.h"

+ 1 - 1
platform/haiku/haiku_direct_window.cpp

@@ -74,7 +74,7 @@ void HaikuDirectWindow::SetMainLoop(MainLoop *p_main_loop) {
 
 
 bool HaikuDirectWindow::QuitRequested() {
 bool HaikuDirectWindow::QuitRequested() {
 	StopMessageRunner();
 	StopMessageRunner();
-	main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
+	main_loop->notification(NOTIFICATION_WM_CLOSE_REQUEST);
 	return false;
 	return false;
 }
 }
 
 

+ 1 - 1
platform/haiku/haiku_direct_window.h

@@ -35,7 +35,7 @@
 
 
 #include <DirectWindow.h>
 #include <DirectWindow.h>
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 
 
 #include "haiku_gl_view.h"
 #include "haiku_gl_view.h"

+ 1 - 1
platform/haiku/os_haiku.h

@@ -33,7 +33,7 @@
 
 
 #include "audio_driver_media_kit.h"
 #include "audio_driver_media_kit.h"
 #include "context_gl_haiku.h"
 #include "context_gl_haiku.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "drivers/unix/os_unix.h"
 #include "drivers/unix/os_unix.h"
 #include "haiku_application.h"
 #include "haiku_application.h"
 #include "haiku_direct_window.h"
 #include "haiku_direct_window.h"

+ 1 - 3
platform/iphone/os_iphone.h

@@ -33,11 +33,9 @@
 #ifndef OS_IPHONE_H
 #ifndef OS_IPHONE_H
 #define OS_IPHONE_H
 #define OS_IPHONE_H
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "drivers/coreaudio/audio_driver_coreaudio.h"
 #include "drivers/coreaudio/audio_driver_coreaudio.h"
 #include "drivers/unix/os_unix.h"
 #include "drivers/unix/os_unix.h"
-
-#include "core/input/input.h"
 #include "game_center.h"
 #include "game_center.h"
 #include "icloud.h"
 #include "icloud.h"
 #include "in_app_store.h"
 #include "in_app_store.h"

+ 6 - 6
platform/javascript/os_javascript.cpp

@@ -1009,10 +1009,10 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
 			update_clipboard(evt.clipboardData.getData('text'));
 			update_clipboard(evt.clipboardData.getData('text'));
 		}, true);
 		}, true);
 	},
 	},
-		MainLoop::NOTIFICATION_WM_MOUSE_ENTER,
-		MainLoop::NOTIFICATION_WM_MOUSE_EXIT,
-		MainLoop::NOTIFICATION_WM_FOCUS_IN,
-		MainLoop::NOTIFICATION_WM_FOCUS_OUT
+		NOTIFICATION_WM_MOUSE_ENTER,
+		NOTIFICATION_WM_MOUSE_EXIT,
+		NOTIFICATION_WM_FOCUS_IN,
+		NOTIFICATION_WM_FOCUS_OUT
 	);
 	);
 	/* clang-format on */
 	/* clang-format on */
 
 
@@ -1121,8 +1121,8 @@ int OS_JavaScript::get_process_id() const {
 
 
 extern "C" EMSCRIPTEN_KEEPALIVE void send_notification(int p_notification) {
 extern "C" EMSCRIPTEN_KEEPALIVE void send_notification(int p_notification) {
 
 
-	if (p_notification == MainLoop::NOTIFICATION_WM_MOUSE_ENTER || p_notification == MainLoop::NOTIFICATION_WM_MOUSE_EXIT) {
-		cursor_inside_canvas = p_notification == MainLoop::NOTIFICATION_WM_MOUSE_ENTER;
+	if (p_notification == NOTIFICATION_WM_MOUSE_ENTER || p_notification == NOTIFICATION_WM_MOUSE_EXIT) {
+		cursor_inside_canvas = p_notification == NOTIFICATION_WM_MOUSE_ENTER;
 	}
 	}
 	OS_JavaScript::get_singleton()->get_main_loop()->notification(p_notification);
 	OS_JavaScript::get_singleton()->get_main_loop()->notification(p_notification);
 }
 }

+ 1 - 1
platform/javascript/os_javascript.h

@@ -32,7 +32,7 @@
 #define OS_JAVASCRIPT_H
 #define OS_JAVASCRIPT_H
 
 
 #include "audio_driver_javascript.h"
 #include "audio_driver_javascript.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "drivers/unix/os_unix.h"
 #include "drivers/unix/os_unix.h"
 #include "servers/audio_server.h"
 #include "servers/audio_server.h"
 #include "servers/visual/rasterizer.h"
 #include "servers/visual/rasterizer.h"

+ 100 - 24
platform/linuxbsd/display_server_x11.cpp

@@ -208,7 +208,7 @@ void DisplayServerX11::_update_real_mouse_position(const WindowData &wd) {
 			last_mouse_pos.x = win_x;
 			last_mouse_pos.x = win_x;
 			last_mouse_pos.y = win_y;
 			last_mouse_pos.y = win_y;
 			last_mouse_pos_valid = true;
 			last_mouse_pos_valid = true;
-			Input::get_singleton()->set_mouse_position(last_mouse_pos);
+			InputFilter::get_singleton()->set_mouse_position(last_mouse_pos);
 		}
 		}
 	}
 	}
 }
 }
@@ -389,7 +389,7 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
 			XWarpPointer(x11_display, None, main_window.x11_window,
 			XWarpPointer(x11_display, None, main_window.x11_window,
 					0, 0, 0, 0, (int)center.x, (int)center.y);
 					0, 0, 0, 0, (int)center.x, (int)center.y);
 
 
-			Input::get_singleton()->set_mouse_position(center);
+			InputFilter::get_singleton()->set_mouse_position(center);
 		}
 		}
 	} else {
 	} else {
 		do_mouse_warp = false;
 		do_mouse_warp = false;
@@ -673,6 +673,29 @@ void DisplayServerX11::window_set_resize_callback(const Callable &p_callable, Wi
 	wd.resize_callback = p_callable;
 	wd.resize_callback = p_callable;
 }
 }
 
 
+void DisplayServerX11::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
+	ERR_FAIL_COND(!windows.has(p_window));
+	WindowData &wd = windows[p_window];
+	wd.event_callback = p_callable;
+}
+
+void DisplayServerX11::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
+	ERR_FAIL_COND(!windows.has(p_window));
+	WindowData &wd = windows[p_window];
+	wd.input_event_callback = p_callable;
+}
+void DisplayServerX11::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
+	ERR_FAIL_COND(!windows.has(p_window));
+	WindowData &wd = windows[p_window];
+	wd.input_text_callback = p_callable;
+}
+
+void DisplayServerX11::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
+	ERR_FAIL_COND(!windows.has(p_window));
+	WindowData &wd = windows[p_window];
+	wd.drop_files_callback = p_callable;
+}
+
 int DisplayServerX11::window_get_current_screen(WindowID p_window) const {
 int DisplayServerX11::window_get_current_screen(WindowID p_window) const {
 	ERR_FAIL_COND_V(!windows.has(p_window), -1);
 	ERR_FAIL_COND_V(!windows.has(p_window), -1);
 	const WindowData &wd = windows[p_window];
 	const WindowData &wd = windows[p_window];
@@ -1837,7 +1860,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
 					k->set_shift(true);
 					k->set_shift(true);
 				}
 				}
 
 
-				Input::get_singleton()->accumulate_input_event(k);
+				InputFilter::get_singleton()->accumulate_input_event(k);
 			}
 			}
 			memfree(utf8string);
 			memfree(utf8string);
 			return;
 			return;
@@ -1979,14 +2002,14 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
 			k->set_metakey(false);
 			k->set_metakey(false);
 	}
 	}
 
 
-	bool last_is_pressed = Input::get_singleton()->is_key_pressed(k->get_keycode());
+	bool last_is_pressed = InputFilter::get_singleton()->is_key_pressed(k->get_keycode());
 	if (k->is_pressed()) {
 	if (k->is_pressed()) {
 		if (last_is_pressed) {
 		if (last_is_pressed) {
 			k->set_echo(true);
 			k->set_echo(true);
 		}
 		}
 	}
 	}
 
 
-	Input::get_singleton()->accumulate_input_event(k);
+	InputFilter::get_singleton()->accumulate_input_event(k);
 }
 }
 
 
 void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data,
 void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data,
@@ -2041,6 +2064,47 @@ void DisplayServerX11::_window_changed(XEvent *event) {
 	}
 	}
 }
 }
 
 
+void DisplayServerX11::_dispatch_input_events(const Ref<InputEvent> &p_event) {
+	((DisplayServerX11 *)(get_singleton()))->_dispatch_input_event(p_event);
+}
+
+void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) {
+
+	Variant ev = p_event;
+	Variant *evp = &ev;
+	Variant ret;
+	Callable::CallError ce;
+
+	Ref<InputEventFromWindow> event_from_window = p_event;
+	if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) {
+		//send to a window
+		ERR_FAIL_COND(!windows.has(event_from_window->get_window_id()));
+		Callable callable = windows[event_from_window->get_window_id()].input_event_callback;
+		if (callable.is_null()) {
+			return;
+		}
+		callable.call((const Variant **)&evp, 1, ret, ce);
+	} else {
+		//send to all windows
+		for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+			Callable callable = E->get().input_event_callback;
+			if (callable.is_null()) {
+				continue;
+			}
+			callable.call((const Variant **)&evp, 1, ret, ce);
+		}
+	}
+}
+
+void DisplayServerX11::_send_window_event(const WindowData &wd, WindowEvent p_event) {
+	if (!wd.event_callback.is_null()) {
+		Variant event = int(p_event);
+		Variant *eventp = &event;
+		Variant ret;
+		Callable::CallError ce;
+		wd.event_callback.call((const Variant **)&eventp, 1, ret, ce);
+	}
+}
 void DisplayServerX11::process_events() {
 void DisplayServerX11::process_events() {
 	do_mouse_warp = false;
 	do_mouse_warp = false;
 
 
@@ -2180,12 +2244,12 @@ void DisplayServerX11::process_events() {
 								// in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out
 								// in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out
 								xi.mouse_pos_to_filter = pos;
 								xi.mouse_pos_to_filter = pos;
 							}
 							}
-							Input::get_singleton()->accumulate_input_event(st);
+							InputFilter::get_singleton()->accumulate_input_event(st);
 						} else {
 						} else {
 							if (!xi.state.has(index)) // Defensive
 							if (!xi.state.has(index)) // Defensive
 								break;
 								break;
 							xi.state.erase(index);
 							xi.state.erase(index);
-							Input::get_singleton()->accumulate_input_event(st);
+							InputFilter::get_singleton()->accumulate_input_event(st);
 						}
 						}
 					} break;
 					} break;
 
 
@@ -2204,7 +2268,7 @@ void DisplayServerX11::process_events() {
 							sd->set_index(index);
 							sd->set_index(index);
 							sd->set_position(pos);
 							sd->set_position(pos);
 							sd->set_relative(pos - curr_pos_elem->value());
 							sd->set_relative(pos - curr_pos_elem->value());
-							Input::get_singleton()->accumulate_input_event(sd);
+							InputFilter::get_singleton()->accumulate_input_event(sd);
 
 
 							curr_pos_elem->value() = pos;
 							curr_pos_elem->value() = pos;
 						}
 						}
@@ -2229,18 +2293,20 @@ void DisplayServerX11::process_events() {
 				minimized = (visibility->state == VisibilityFullyObscured);
 				minimized = (visibility->state == VisibilityFullyObscured);
 			} break;
 			} break;
 			case LeaveNotify: {
 			case LeaveNotify: {
-				if (!mouse_mode_grab)
-					Input::get_singleton()->parse_notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
+				if (!mouse_mode_grab) {
+					_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
+				}
 
 
 			} break;
 			} break;
 			case EnterNotify: {
 			case EnterNotify: {
-				if (!mouse_mode_grab)
-					Input::get_singleton()->parse_notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
+				if (!mouse_mode_grab) {
+					_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
+				}
 			} break;
 			} break;
 			case FocusIn:
 			case FocusIn:
 				minimized = false;
 				minimized = false;
 				window_has_focus = true;
 				window_has_focus = true;
-				Input::get_singleton()->parse_notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+				_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN);
 				window_focused = true;
 				window_focused = true;
 
 
 				if (mouse_mode_grab) {
 				if (mouse_mode_grab) {
@@ -2272,8 +2338,8 @@ void DisplayServerX11::process_events() {
 
 
 			case FocusOut:
 			case FocusOut:
 				window_has_focus = false;
 				window_has_focus = false;
-				Input::get_singleton()->release_pressed_events();
-				Input::get_singleton()->parse_notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+				InputFilter::get_singleton()->release_pressed_events();
+				_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT);
 				window_focused = false;
 				window_focused = false;
 
 
 				if (mouse_mode_grab) {
 				if (mouse_mode_grab) {
@@ -2301,7 +2367,7 @@ void DisplayServerX11::process_events() {
 					st->set_index(E->key());
 					st->set_index(E->key());
 					st->set_window_id(window_id);
 					st->set_window_id(window_id);
 					st->set_position(E->get());
 					st->set_position(E->get());
-					Input::get_singleton()->accumulate_input_event(st);
+					InputFilter::get_singleton()->accumulate_input_event(st);
 				}
 				}
 				xi.state.clear();
 				xi.state.clear();
 #endif
 #endif
@@ -2363,7 +2429,7 @@ void DisplayServerX11::process_events() {
 					}
 					}
 				}
 				}
 
 
-				Input::get_singleton()->accumulate_input_event(mb);
+				InputFilter::get_singleton()->accumulate_input_event(mb);
 
 
 			} break;
 			} break;
 			case MotionNotify: {
 			case MotionNotify: {
@@ -2465,8 +2531,8 @@ void DisplayServerX11::process_events() {
 				mm->set_button_mask(mouse_get_button_state());
 				mm->set_button_mask(mouse_get_button_state());
 				mm->set_position(posi);
 				mm->set_position(posi);
 				mm->set_global_position(posi);
 				mm->set_global_position(posi);
-				Input::get_singleton()->set_mouse_position(posi);
-				mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
+				InputFilter::get_singleton()->set_mouse_position(posi);
+				mm->set_speed(InputFilter::get_singleton()->get_last_mouse_speed());
 
 
 				mm->set_relative(rel);
 				mm->set_relative(rel);
 
 
@@ -2477,7 +2543,7 @@ void DisplayServerX11::process_events() {
 				// this is so that the relative motion doesn't get messed up
 				// this is so that the relative motion doesn't get messed up
 				// after we regain focus.
 				// after we regain focus.
 				if (window_has_focus || !mouse_mode_grab)
 				if (window_has_focus || !mouse_mode_grab)
-					Input::get_singleton()->accumulate_input_event(mm);
+					InputFilter::get_singleton()->accumulate_input_event(mm);
 
 
 			} break;
 			} break;
 			case KeyPress:
 			case KeyPress:
@@ -2561,7 +2627,14 @@ void DisplayServerX11::process_events() {
 					for (int i = 0; i < files.size(); i++) {
 					for (int i = 0; i < files.size(); i++) {
 						files.write[i] = files[i].replace("file://", "").http_unescape().strip_edges();
 						files.write[i] = files[i].replace("file://", "").http_unescape().strip_edges();
 					}
 					}
-					Input::get_singleton()->parse_drop_files(files);
+
+					if (!windows[window_id].drop_files_callback.is_null()) {
+						Variant v = files;
+						Variant *vp = &v;
+						Variant ret;
+						Callable::CallError ce;
+						windows[window_id].drop_files_callback.call((const Variant **)&vp, 1, ret, ce);
+					}
 
 
 					//Reply that all is well.
 					//Reply that all is well.
 					XClientMessageEvent m;
 					XClientMessageEvent m;
@@ -2581,8 +2654,9 @@ void DisplayServerX11::process_events() {
 
 
 			case ClientMessage:
 			case ClientMessage:
 
 
-				if ((unsigned int)event.xclient.data.l[0] == (unsigned int)wm_delete)
-					Input::get_singleton()->parse_notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
+				if ((unsigned int)event.xclient.data.l[0] == (unsigned int)wm_delete) {
+					_send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST);
+				}
 
 
 				else if ((unsigned int)event.xclient.message_type == (unsigned int)xdnd_enter) {
 				else if ((unsigned int)event.xclient.message_type == (unsigned int)xdnd_enter) {
 
 
@@ -2662,7 +2736,7 @@ void DisplayServerX11::process_events() {
 		*/
 		*/
 	}
 	}
 
 
-	Input::get_singleton()->flush_accumulated_events();
+	InputFilter::get_singleton()->flush_accumulated_events();
 }
 }
 
 
 void DisplayServerX11::release_rendering_thread() {
 void DisplayServerX11::release_rendering_thread() {
@@ -2881,6 +2955,8 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, c
 
 
 DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
 DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
 
 
+	InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
+
 	r_error = OK;
 	r_error = OK;
 
 
 	last_button_state = 0;
 	last_button_state = 0;

+ 13 - 1
platform/linuxbsd/display_server_x11.h

@@ -35,7 +35,7 @@
 
 
 #include "servers/display_server.h"
 #include "servers/display_server.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 
 
 #include "drivers/alsa/audio_driver_alsa.h"
 #include "drivers/alsa/audio_driver_alsa.h"
 #include "drivers/alsamidi/midi_driver_alsamidi.h"
 #include "drivers/alsamidi/midi_driver_alsamidi.h"
@@ -120,6 +120,10 @@ class DisplayServerX11 : public DisplayServer {
 		Size2i im_position;
 		Size2i im_position;
 		bool im_active = false;
 		bool im_active = false;
 		Callable resize_callback;
 		Callable resize_callback;
+		Callable event_callback;
+		Callable input_event_callback;
+		Callable input_text_callback;
+		Callable drop_files_callback;
 
 
 		//better to guess on the fly, given WM can change it
 		//better to guess on the fly, given WM can change it
 		//WindowMode mode;
 		//WindowMode mode;
@@ -224,6 +228,10 @@ class DisplayServerX11 : public DisplayServer {
 
 
 	Context context = CONTEXT_ENGINE;
 	Context context = CONTEXT_ENGINE;
 
 
+	void _send_window_event(const WindowData &wd, WindowEvent p_event);
+	static void _dispatch_input_events(const Ref<InputEvent> &p_event);
+	void _dispatch_input_event(const Ref<InputEvent> &p_event);
+
 protected:
 protected:
 	void _window_changed(XEvent *event);
 	void _window_changed(XEvent *event);
 
 
@@ -256,6 +264,10 @@ public:
 
 
 	virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID);
 	virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID);
 	virtual void window_set_resize_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
 	virtual void window_set_resize_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+	virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+	virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+	virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+	virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
 
 
 	virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const;
 	virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const;
 	virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID);
 	virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID);

+ 11 - 11
platform/linuxbsd/joypad_linux.cpp

@@ -71,7 +71,7 @@ void JoypadLinux::Joypad::reset() {
 	dpad = 0;
 	dpad = 0;
 	fd = -1;
 	fd = -1;
 
 
-	Input::JoyAxis jx;
+	InputFilter::JoyAxis jx;
 	jx.min = -1;
 	jx.min = -1;
 	jx.value = 0.0f;
 	jx.value = 0.0f;
 	for (int i = 0; i < MAX_ABS; i++) {
 	for (int i = 0; i < MAX_ABS; i++) {
@@ -80,7 +80,7 @@ void JoypadLinux::Joypad::reset() {
 	}
 	}
 }
 }
 
 
-JoypadLinux::JoypadLinux(Input *in) {
+JoypadLinux::JoypadLinux(InputFilter *in) {
 	exit_udev = false;
 	exit_udev = false;
 	input = in;
 	input = in;
 	joy_thread = Thread::create(joy_thread_func, this);
 	joy_thread = Thread::create(joy_thread_func, this);
@@ -436,11 +436,11 @@ void JoypadLinux::joypad_vibration_stop(int p_id, uint64_t p_timestamp) {
 	joy.ff_effect_timestamp = p_timestamp;
 	joy.ff_effect_timestamp = p_timestamp;
 }
 }
 
 
-Input::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const {
+InputFilter::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const {
 
 
 	int min = p_abs->minimum;
 	int min = p_abs->minimum;
 	int max = p_abs->maximum;
 	int max = p_abs->maximum;
-	Input::JoyAxis jx;
+	InputFilter::JoyAxis jx;
 
 
 	if (min < 0) {
 	if (min < 0) {
 		jx.min = -1;
 		jx.min = -1;
@@ -492,11 +492,11 @@ void JoypadLinux::process_joypads() {
 							case ABS_HAT0X:
 							case ABS_HAT0X:
 								if (ev.value != 0) {
 								if (ev.value != 0) {
 									if (ev.value < 0)
 									if (ev.value < 0)
-										joy->dpad |= Input::HAT_MASK_LEFT;
+										joy->dpad |= InputFilter::HAT_MASK_LEFT;
 									else
 									else
-										joy->dpad |= Input::HAT_MASK_RIGHT;
+										joy->dpad |= InputFilter::HAT_MASK_RIGHT;
 								} else
 								} else
-									joy->dpad &= ~(Input::HAT_MASK_LEFT | Input::HAT_MASK_RIGHT);
+									joy->dpad &= ~(InputFilter::HAT_MASK_LEFT | InputFilter::HAT_MASK_RIGHT);
 
 
 								input->joy_hat(i, joy->dpad);
 								input->joy_hat(i, joy->dpad);
 								break;
 								break;
@@ -504,11 +504,11 @@ void JoypadLinux::process_joypads() {
 							case ABS_HAT0Y:
 							case ABS_HAT0Y:
 								if (ev.value != 0) {
 								if (ev.value != 0) {
 									if (ev.value < 0)
 									if (ev.value < 0)
-										joy->dpad |= Input::HAT_MASK_UP;
+										joy->dpad |= InputFilter::HAT_MASK_UP;
 									else
 									else
-										joy->dpad |= Input::HAT_MASK_DOWN;
+										joy->dpad |= InputFilter::HAT_MASK_DOWN;
 								} else
 								} else
-									joy->dpad &= ~(Input::HAT_MASK_UP | Input::HAT_MASK_DOWN);
+									joy->dpad &= ~(InputFilter::HAT_MASK_UP | InputFilter::HAT_MASK_DOWN);
 
 
 								input->joy_hat(i, joy->dpad);
 								input->joy_hat(i, joy->dpad);
 								break;
 								break;
@@ -517,7 +517,7 @@ void JoypadLinux::process_joypads() {
 								if (ev.code >= MAX_ABS)
 								if (ev.code >= MAX_ABS)
 									return;
 									return;
 								if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) {
 								if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) {
-									Input::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value);
+									InputFilter::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value);
 									joy->curr_axis[joy->abs_map[ev.code]] = value;
 									joy->curr_axis[joy->abs_map[ev.code]] = value;
 								}
 								}
 								break;
 								break;

+ 5 - 5
platform/linuxbsd/joypad_linux.h

@@ -33,7 +33,7 @@
 #define JOYPAD_LINUX_H
 #define JOYPAD_LINUX_H
 
 
 #ifdef JOYDEV_ENABLED
 #ifdef JOYDEV_ENABLED
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/mutex.h"
 #include "core/os/mutex.h"
 #include "core/os/thread.h"
 #include "core/os/thread.h"
 
 
@@ -41,7 +41,7 @@ struct input_absinfo;
 
 
 class JoypadLinux {
 class JoypadLinux {
 public:
 public:
-	JoypadLinux(Input *in);
+	JoypadLinux(InputFilter *in);
 	~JoypadLinux();
 	~JoypadLinux();
 	void process_joypads();
 	void process_joypads();
 
 
@@ -53,7 +53,7 @@ private:
 	};
 	};
 
 
 	struct Joypad {
 	struct Joypad {
-		Input::JoyAxis curr_axis[MAX_ABS];
+		InputFilter::JoyAxis curr_axis[MAX_ABS];
 		int key_map[MAX_KEY];
 		int key_map[MAX_KEY];
 		int abs_map[MAX_ABS];
 		int abs_map[MAX_ABS];
 		int dpad;
 		int dpad;
@@ -74,7 +74,7 @@ private:
 	bool exit_udev;
 	bool exit_udev;
 	Mutex joy_mutex;
 	Mutex joy_mutex;
 	Thread *joy_thread;
 	Thread *joy_thread;
-	Input *input;
+	InputFilter *input;
 	Joypad joypads[JOYPADS_MAX];
 	Joypad joypads[JOYPADS_MAX];
 	Vector<String> attached_devices;
 	Vector<String> attached_devices;
 
 
@@ -95,7 +95,7 @@ private:
 	void joypad_vibration_start(int p_id, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
 	void joypad_vibration_start(int p_id, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
 	void joypad_vibration_stop(int p_id, uint64_t p_timestamp);
 	void joypad_vibration_stop(int p_id, uint64_t p_timestamp);
 
 
-	Input::JoyAxis axis_correct(const input_absinfo *p_abs, int p_value) const;
+	InputFilter::JoyAxis axis_correct(const input_absinfo *p_abs, int p_value) const;
 };
 };
 
 
 #endif
 #endif

+ 1 - 1
platform/linuxbsd/os_linuxbsd.cpp

@@ -64,7 +64,7 @@ void OS_LinuxBSD::initialize() {
 void OS_LinuxBSD::initialize_joypads() {
 void OS_LinuxBSD::initialize_joypads() {
 
 
 #ifdef JOYDEV_ENABLED
 #ifdef JOYDEV_ENABLED
-	joypad = memnew(JoypadLinux(Input::get_singleton()));
+	joypad = memnew(JoypadLinux(InputFilter::get_singleton()));
 #endif
 #endif
 }
 }
 
 

+ 1 - 1
platform/linuxbsd/os_linuxbsd.h

@@ -31,7 +31,7 @@
 #ifndef OS_LINUXBSD_H
 #ifndef OS_LINUXBSD_H
 #define OS_LINUXBSD_H
 #define OS_LINUXBSD_H
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "crash_handler_linuxbsd.h"
 #include "crash_handler_linuxbsd.h"
 #include "drivers/alsa/audio_driver_alsa.h"
 #include "drivers/alsa/audio_driver_alsa.h"
 #include "drivers/alsamidi/midi_driver_alsamidi.h"
 #include "drivers/alsamidi/midi_driver_alsamidi.h"

+ 1 - 1
platform/osx/joypad_osx.cpp

@@ -573,7 +573,7 @@ void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const {
 
 
 JoypadOSX::JoypadOSX() {
 JoypadOSX::JoypadOSX() {
 	self = this;
 	self = this;
-	input = (InputDefault *)Input::get_singleton();
+	input = (InputDefault *)InputFilter::get_singleton();
 
 
 	int okay = 1;
 	int okay = 1;
 	const void *vals[] = {
 	const void *vals[] = {

+ 1 - 1
platform/osx/joypad_osx.h

@@ -40,7 +40,7 @@
 #include <ForceFeedback/ForceFeedbackConstants.h>
 #include <ForceFeedback/ForceFeedbackConstants.h>
 #include <IOKit/hid/IOHIDLib.h>
 #include <IOKit/hid/IOHIDLib.h>
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 
 
 struct rec_element {
 struct rec_element {
 	IOHIDElementRef ref;
 	IOHIDElementRef ref;

+ 1 - 1
platform/osx/os_osx.h

@@ -33,7 +33,7 @@
 
 
 #define BitMap _QDBitMap // Suppress deprecated QuickDraw definition.
 #define BitMap _QDBitMap // Suppress deprecated QuickDraw definition.
 
 
-#include "core/input/input.h"
+#include "core/input/inpu_filter.h"
 #include "crash_handler_osx.h"
 #include "crash_handler_osx.h"
 #include "drivers/coreaudio/audio_driver_coreaudio.h"
 #include "drivers/coreaudio/audio_driver_coreaudio.h"
 #include "drivers/coremidi/midi_driver_coremidi.h"
 #include "drivers/coremidi/midi_driver_coremidi.h"

+ 1 - 1
platform/server/os_server.h

@@ -31,7 +31,7 @@
 #ifndef OS_SERVER_H
 #ifndef OS_SERVER_H
 #define OS_SERVER_H
 #define OS_SERVER_H
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "drivers/dummy/texture_loader_dummy.h"
 #include "drivers/dummy/texture_loader_dummy.h"
 #include "drivers/unix/os_unix.h"
 #include "drivers/unix/os_unix.h"
 #ifdef __APPLE__
 #ifdef __APPLE__

+ 1 - 1
platform/uwp/joypad_uwp.h

@@ -31,7 +31,7 @@
 #ifndef JOYPAD_UWP_H
 #ifndef JOYPAD_UWP_H
 #define JOYPAD_UWP_H
 #define JOYPAD_UWP_H
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 
 
 ref class JoypadUWP sealed {
 ref class JoypadUWP sealed {
 
 

+ 1 - 1
platform/uwp/os_uwp.h

@@ -32,7 +32,7 @@
 #define OS_UWP_H
 #define OS_UWP_H
 
 
 #include "context_egl_uwp.h"
 #include "context_egl_uwp.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/math/transform_2d.h"
 #include "core/math/transform_2d.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "core/ustring.h"
 #include "core/ustring.h"

+ 7 - 7
platform/windows/os_windows.cpp

@@ -361,14 +361,14 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 			};
 			};
 			if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) {
 			if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) {
 
 
-				main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+				main_loop->notification(NOTIFICATION_WM_FOCUS_IN);
 				window_focused = true;
 				window_focused = true;
 				alt_mem = false;
 				alt_mem = false;
 				control_mem = false;
 				control_mem = false;
 				shift_mem = false;
 				shift_mem = false;
 			} else { // WM_INACTIVE
 			} else { // WM_INACTIVE
 				input->release_pressed_events();
 				input->release_pressed_events();
-				main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+				main_loop->notification(NOTIFICATION_WM_FOCUS_OUT);
 				window_focused = false;
 				window_focused = false;
 				alt_mem = false;
 				alt_mem = false;
 			};
 			};
@@ -414,7 +414,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 		case WM_CLOSE: // Did We Receive A Close Message?
 		case WM_CLOSE: // Did We Receive A Close Message?
 		{
 		{
 			if (main_loop)
 			if (main_loop)
-				main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
+				main_loop->notification(NOTIFICATION_WM_CLOSE_REQUEST);
 			//force_quit=true;
 			//force_quit=true;
 			return 0; // Jump Back
 			return 0; // Jump Back
 		}
 		}
@@ -423,7 +423,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 			old_invalid = true;
 			old_invalid = true;
 			outside = true;
 			outside = true;
 			if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
 			if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
-				main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
+				main_loop->notification(NOTIFICATION_WM_MOUSE_EXIT);
 
 
 		} break;
 		} break;
 		case WM_INPUT: {
 		case WM_INPUT: {
@@ -536,7 +536,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 				//mouse enter
 				//mouse enter
 
 
 				if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
 				if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
-					main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
+					main_loop->notification(NOTIFICATION_WM_MOUSE_ENTER);
 
 
 				CursorShape c = cursor_shape;
 				CursorShape c = cursor_shape;
 				cursor_shape = CURSOR_MAX;
 				cursor_shape = CURSOR_MAX;
@@ -630,7 +630,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 				//mouse enter
 				//mouse enter
 
 
 				if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
 				if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
-					main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
+					main_loop->notification(NOTIFICATION_WM_MOUSE_ENTER);
 
 
 				CursorShape c = cursor_shape;
 				CursorShape c = cursor_shape;
 				cursor_shape = CURSOR_MAX;
 				cursor_shape = CURSOR_MAX;
@@ -974,7 +974,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 				// When SetCapture is used, ALT+F4 hotkey is ignored by Windows, so handle it ourselves
 				// When SetCapture is used, ALT+F4 hotkey is ignored by Windows, so handle it ourselves
 				if (wParam == VK_F4 && alt_mem && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)) {
 				if (wParam == VK_F4 && alt_mem && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)) {
 					if (main_loop)
 					if (main_loop)
-						main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
+						main_loop->notification(NOTIFICATION_WM_CLOSE_REQUEST);
 				}
 				}
 			}
 			}
 			/*
 			/*

+ 1 - 1
platform/windows/os_windows.h

@@ -31,7 +31,7 @@
 #ifndef OS_WINDOWS_H
 #ifndef OS_WINDOWS_H
 #define OS_WINDOWS_H
 #define OS_WINDOWS_H
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 #include "crash_handler_windows.h"
 #include "crash_handler_windows.h"

+ 1 - 1
scene/2d/canvas_item.cpp

@@ -30,7 +30,7 @@
 
 
 #include "canvas_item.h"
 #include "canvas_item.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/message_queue.h"
 #include "core/message_queue.h"
 #include "core/method_bind_ext.gen.inc"
 #include "core/method_bind_ext.gen.inc"
 #include "scene/main/canvas_layer.h"
 #include "scene/main/canvas_layer.h"

+ 6 - 6
scene/2d/touch_screen_button.cpp

@@ -30,11 +30,11 @@
 
 
 #include "touch_screen_button.h"
 #include "touch_screen_button.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/input/input_map.h"
 #include "core/input/input_map.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "scene/main/window.h"
 #include "scene/main/window.h"
-
+#
 void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) {
 void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) {
 
 
 	texture = p_texture;
 	texture = p_texture;
@@ -290,12 +290,12 @@ void TouchScreenButton::_press(int p_finger_pressed) {
 
 
 	if (action != StringName()) {
 	if (action != StringName()) {
 
 
-		Input::get_singleton()->action_press(action);
+		InputFilter::get_singleton()->action_press(action);
 		Ref<InputEventAction> iea;
 		Ref<InputEventAction> iea;
 		iea.instance();
 		iea.instance();
 		iea->set_action(action);
 		iea->set_action(action);
 		iea->set_pressed(true);
 		iea->set_pressed(true);
-		get_tree()->input_event(iea);
+		get_viewport()->input(iea, true);
 	}
 	}
 
 
 	emit_signal("pressed");
 	emit_signal("pressed");
@@ -308,14 +308,14 @@ void TouchScreenButton::_release(bool p_exiting_tree) {
 
 
 	if (action != StringName()) {
 	if (action != StringName()) {
 
 
-		Input::get_singleton()->action_release(action);
+		InputFilter::get_singleton()->action_release(action);
 		if (!p_exiting_tree) {
 		if (!p_exiting_tree) {
 
 
 			Ref<InputEventAction> iea;
 			Ref<InputEventAction> iea;
 			iea.instance();
 			iea.instance();
 			iea->set_action(action);
 			iea->set_action(action);
 			iea->set_pressed(false);
 			iea->set_pressed(false);
-			get_tree()->input_event(iea);
+			get_viewport()->input(iea, true);
 		}
 		}
 	}
 	}
 
 

+ 4 - 4
scene/3d/arvr_nodes.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "arvr_nodes.h"
 #include "arvr_nodes.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "servers/arvr/arvr_interface.h"
 #include "servers/arvr/arvr_interface.h"
 #include "servers/arvr_server.h"
 #include "servers/arvr_server.h"
 
 
@@ -206,7 +206,7 @@ void ARVRController::_notification(int p_what) {
 					// check button states
 					// check button states
 					for (int i = 0; i < 16; i++) {
 					for (int i = 0; i < 16; i++) {
 						bool was_pressed = (button_states & mask) == mask;
 						bool was_pressed = (button_states & mask) == mask;
-						bool is_pressed = Input::get_singleton()->is_joy_button_pressed(joy_id, i);
+						bool is_pressed = InputFilter::get_singleton()->is_joy_button_pressed(joy_id, i);
 
 
 						if (!was_pressed && is_pressed) {
 						if (!was_pressed && is_pressed) {
 							emit_signal("button_pressed", i);
 							emit_signal("button_pressed", i);
@@ -306,7 +306,7 @@ bool ARVRController::is_button_pressed(int p_button) const {
 		return false;
 		return false;
 	};
 	};
 
 
-	return Input::get_singleton()->is_joy_button_pressed(joy_id, p_button);
+	return InputFilter::get_singleton()->is_joy_button_pressed(joy_id, p_button);
 };
 };
 
 
 float ARVRController::get_joystick_axis(int p_axis) const {
 float ARVRController::get_joystick_axis(int p_axis) const {
@@ -315,7 +315,7 @@ float ARVRController::get_joystick_axis(int p_axis) const {
 		return 0.0;
 		return 0.0;
 	};
 	};
 
 
-	return Input::get_singleton()->get_joy_axis(joy_id, p_axis);
+	return InputFilter::get_singleton()->get_joy_axis(joy_id, p_axis);
 };
 };
 
 
 real_t ARVRController::get_rumble() const {
 real_t ARVRController::get_rumble() const {

+ 3 - 3
scene/gui/color_picker.cpp

@@ -30,7 +30,7 @@
 
 
 #include "color_picker.h"
 #include "color_picker.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 
 
@@ -78,7 +78,7 @@ void ColorPicker::_notification(int p_what) {
 			if (p)
 			if (p)
 				p->set_size(Size2(get_combined_minimum_size().width + get_constant("margin") * 2, get_combined_minimum_size().height + get_constant("margin") * 2));
 				p->set_size(Size2(get_combined_minimum_size().width + get_constant("margin") * 2, get_combined_minimum_size().height + get_constant("margin") * 2));
 		} break;
 		} break;
-		case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: {
+		case NOTIFICATION_WM_CLOSE_REQUEST: {
 
 
 			if (screen != NULL && screen->is_visible())
 			if (screen != NULL && screen->is_visible())
 				screen->hide();
 				screen->hide();
@@ -902,7 +902,7 @@ void ColorPickerButton::_notification(int p_what) {
 				draw_texture(Control::get_icon("overbright_indicator", "ColorPicker"), normal->get_offset());
 				draw_texture(Control::get_icon("overbright_indicator", "ColorPicker"), normal->get_offset());
 			}
 			}
 		} break;
 		} break;
-		case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: {
+		case NOTIFICATION_WM_CLOSE_REQUEST: {
 
 
 			if (popup)
 			if (popup)
 				popup->hide();
 				popup->hide();

+ 0 - 5
scene/gui/control.cpp

@@ -667,11 +667,6 @@ void Control::_notification(int p_notification) {
 			}
 			}
 
 
 		} break;
 		} break;
-		case SceneTree::NOTIFICATION_WM_UNFOCUS_REQUEST: {
-
-			get_viewport()->_gui_unfocus_control(this);
-
-		} break;
 	}
 	}
 }
 }
 
 

+ 10 - 10
scene/gui/graph_edit.cpp

@@ -30,7 +30,7 @@
 
 
 #include "graph_edit.h"
 #include "graph_edit.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "scene/gui/box_container.h"
 #include "scene/gui/box_container.h"
 
 
@@ -804,7 +804,7 @@ void GraphEdit::set_selected(Node *p_child) {
 void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
 void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
 
 
 	Ref<InputEventMouseMotion> mm = p_ev;
 	Ref<InputEventMouseMotion> mm = p_ev;
-	if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) {
+	if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)))) {
 		h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x);
 		h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x);
 		v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y);
 		v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y);
 	}
 	}
@@ -823,7 +823,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
 
 
 				// Snapping can be toggled temporarily by holding down Ctrl.
 				// Snapping can be toggled temporarily by holding down Ctrl.
 				// This is done here as to not toggle the grid when holding down Ctrl.
 				// This is done here as to not toggle the grid when holding down Ctrl.
-				if (is_using_snap() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+				if (is_using_snap() ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
 					const int snap = get_snap();
 					const int snap = get_snap();
 					pos = pos.snapped(Vector2(snap, snap));
 					pos = pos.snapped(Vector2(snap, snap));
 				}
 				}
@@ -886,7 +886,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
 		}
 		}
 
 
 		if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) {
 		if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) {
-			if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+			if (!just_selected && drag_accum == Vector2() && InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
 				//deselect current node
 				//deselect current node
 				for (int i = get_child_count() - 1; i >= 0; i--) {
 				for (int i = get_child_count() - 1; i >= 0; i--) {
 					GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
 					GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
@@ -948,7 +948,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
 				drag_accum = Vector2();
 				drag_accum = Vector2();
 				drag_origin = get_local_mouse_position();
 				drag_origin = get_local_mouse_position();
 				just_selected = !gn->is_selected();
 				just_selected = !gn->is_selected();
-				if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+				if (!gn->is_selected() && !InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
 					for (int i = 0; i < get_child_count(); i++) {
 					for (int i = 0; i < get_child_count(); i++) {
 						GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i));
 						GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i));
 						if (o_gn)
 						if (o_gn)
@@ -968,7 +968,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
 			} else {
 			} else {
 				if (_filter_input(b->get_position()))
 				if (_filter_input(b->get_position()))
 					return;
 					return;
-				if (Input::get_singleton()->is_key_pressed(KEY_SPACE))
+				if (InputFilter::get_singleton()->is_key_pressed(KEY_SPACE))
 					return;
 					return;
 
 
 				box_selecting = true;
 				box_selecting = true;
@@ -1025,16 +1025,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
 			//too difficult to get right
 			//too difficult to get right
 			//set_zoom(zoom/ZOOM_SCALE);
 			//set_zoom(zoom/ZOOM_SCALE);
 		}
 		}
-		if (b->get_button_index() == BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+		if (b->get_button_index() == BUTTON_WHEEL_UP && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 			v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
 			v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
 		}
 		}
-		if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+		if (b->get_button_index() == BUTTON_WHEEL_DOWN && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
 			v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8);
 			v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8);
 		}
 		}
-		if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
+		if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT))) {
 			h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8);
 			h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8);
 		}
 		}
-		if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
+		if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT))) {
 			h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8);
 			h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8);
 		}
 		}
 	}
 	}

+ 2 - 2
scene/gui/line_edit.cpp

@@ -685,12 +685,12 @@ void LineEdit::_notification(int p_what) {
 			update_placeholder_width();
 			update_placeholder_width();
 			update();
 			update();
 		} break;
 		} break;
-		case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
+		case NOTIFICATION_WM_FOCUS_IN: {
 			window_has_focus = true;
 			window_has_focus = true;
 			draw_caret = true;
 			draw_caret = true;
 			update();
 			update();
 		} break;
 		} break;
-		case MainLoop::NOTIFICATION_WM_FOCUS_OUT: {
+		case NOTIFICATION_WM_FOCUS_OUT: {
 			window_has_focus = false;
 			window_has_focus = false;
 			draw_caret = false;
 			draw_caret = false;
 			update();
 			update();

+ 3 - 3
scene/gui/popup_menu.cpp

@@ -30,7 +30,7 @@
 
 
 #include "popup_menu.h"
 #include "popup_menu.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "core/print_string.h"
 #include "core/print_string.h"
@@ -587,7 +587,7 @@ void PopupMenu::_notification(int p_what) {
 				ofs.y += h;
 				ofs.y += h;
 			}
 			}
 		} break;
 		} break;
-		case MainLoop::NOTIFICATION_WM_FOCUS_OUT: {
+		case NOTIFICATION_WM_FOCUS_OUT: {
 
 
 			if (hide_on_window_lose_focus)
 			if (hide_on_window_lose_focus)
 				hide();
 				hide();
@@ -605,7 +605,7 @@ void PopupMenu::_notification(int p_what) {
 		} break;
 		} break;
 		case NOTIFICATION_POST_POPUP: {
 		case NOTIFICATION_POST_POPUP: {
 
 
-			initial_button_mask = Input::get_singleton()->get_mouse_button_mask();
+			initial_button_mask = InputFilter::get_singleton()->get_mouse_button_mask();
 			during_grabbed_click = (bool)initial_button_mask;
 			during_grabbed_click = (bool)initial_button_mask;
 		} break;
 		} break;
 		case NOTIFICATION_POPUP_HIDE: {
 		case NOTIFICATION_POPUP_HIDE: {

+ 5 - 4
scene/gui/spin_box.cpp

@@ -29,7 +29,8 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "spin_box.h"
 #include "spin_box.h"
-#include "core/input/input.h"
+
+#include "core/input/input_filter.h"
 #include "core/math/expression.h"
 #include "core/math/expression.h"
 
 
 Size2 SpinBox::get_minimum_size() const {
 Size2 SpinBox::get_minimum_size() const {
@@ -76,7 +77,7 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) {
 
 
 void SpinBox::_range_click_timeout() {
 void SpinBox::_range_click_timeout() {
 
 
-	if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+	if (!drag.enabled && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
 
 
 		bool up = get_local_mouse_position().y < (get_size().height / 2);
 		bool up = get_local_mouse_position().y < (get_size().height / 2);
 		set_value(get_value() + (up ? get_step() : -get_step()));
 		set_value(get_value() + (up ? get_step() : -get_step()));
@@ -148,7 +149,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
 
 
 		if (drag.enabled) {
 		if (drag.enabled) {
 			drag.enabled = false;
 			drag.enabled = false;
-			Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+			InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
 			warp_mouse(drag.capture_pos);
 			warp_mouse(drag.capture_pos);
 		}
 		}
 		drag.allowed = false;
 		drag.allowed = false;
@@ -165,7 +166,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
 			set_value(CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max()));
 			set_value(CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max()));
 		} else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) {
 		} else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) {
 
 
-			Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
+			InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED);
 			drag.enabled = true;
 			drag.enabled = true;
 			drag.base_val = get_value();
 			drag.base_val = get_value();
 			drag.diff_y = 0;
 			drag.diff_y = 0;

+ 4 - 4
scene/gui/text_edit.cpp

@@ -30,7 +30,7 @@
 
 
 #include "text_edit.h"
 #include "text_edit.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/message_queue.h"
 #include "core/message_queue.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
@@ -446,7 +446,7 @@ void TextEdit::_click_selection_held() {
 	// Warning: is_mouse_button_pressed(BUTTON_LEFT) returns false for double+ clicks, so this doesn't work for MODE_WORD
 	// Warning: is_mouse_button_pressed(BUTTON_LEFT) returns false for double+ clicks, so this doesn't work for MODE_WORD
 	// and MODE_LINE. However, moving the mouse triggers _gui_input, which calls these functions too, so that's not a huge problem.
 	// and MODE_LINE. However, moving the mouse triggers _gui_input, which calls these functions too, so that's not a huge problem.
 	// I'm unsure if there's an actual fix that doesn't have a ton of side effects.
 	// I'm unsure if there's an actual fix that doesn't have a ton of side effects.
-	if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) {
+	if (InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) {
 		switch (selection.selecting_mode) {
 		switch (selection.selecting_mode) {
 			case Selection::MODE_POINTER: {
 			case Selection::MODE_POINTER: {
 				_update_selection_mode_pointer();
 				_update_selection_mode_pointer();
@@ -639,12 +639,12 @@ void TextEdit::_notification(int p_what) {
 			_update_wrap_at();
 			_update_wrap_at();
 			syntax_highlighting_cache.clear();
 			syntax_highlighting_cache.clear();
 		} break;
 		} break;
-		case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
+		case NOTIFICATION_WM_FOCUS_IN: {
 			window_has_focus = true;
 			window_has_focus = true;
 			draw_caret = true;
 			draw_caret = true;
 			update();
 			update();
 		} break;
 		} break;
-		case MainLoop::NOTIFICATION_WM_FOCUS_OUT: {
+		case NOTIFICATION_WM_FOCUS_OUT: {
 			window_has_focus = false;
 			window_has_focus = false;
 			draw_caret = false;
 			draw_caret = false;
 			update();
 			update();

+ 9 - 9
scene/gui/tree.cpp

@@ -30,7 +30,7 @@
 
 
 #include "tree.h"
 #include "tree.h"
 
 
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/math/math_funcs.h"
 #include "core/math/math_funcs.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
@@ -1423,7 +1423,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
 
 
 					if (p_item->cells[i].custom_button) {
 					if (p_item->cells[i].custom_button) {
 						if (cache.hover_item == p_item && cache.hover_cell == i) {
 						if (cache.hover_item == p_item && cache.hover_cell == i) {
-							if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+							if (InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
 								draw_style_box(cache.custom_button_pressed, ir);
 								draw_style_box(cache.custom_button_pressed, ir);
 							} else {
 							} else {
 								draw_style_box(cache.custom_button_hover, ir);
 								draw_style_box(cache.custom_button_hover, ir);
@@ -1659,7 +1659,7 @@ Rect2 Tree::search_item_rect(TreeItem *p_from, TreeItem *p_item) {
 
 
 void Tree::_range_click_timeout() {
 void Tree::_range_click_timeout() {
 
 
-	if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+	if (range_item_last && !range_drag_enabled && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
 
 
 		Point2 pos = get_local_mouse_position() - cache.bg->get_offset();
 		Point2 pos = get_local_mouse_position() - cache.bg->get_offset();
 		if (show_column_titles) {
 		if (show_column_titles) {
@@ -2046,9 +2046,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
 
 
 void Tree::_text_editor_modal_close() {
 void Tree::_text_editor_modal_close() {
 
 
-	if (Input::get_singleton()->is_key_pressed(KEY_ESCAPE) ||
-			Input::get_singleton()->is_key_pressed(KEY_KP_ENTER) ||
-			Input::get_singleton()->is_key_pressed(KEY_ENTER)) {
+	if (InputFilter::get_singleton()->is_key_pressed(KEY_ESCAPE) ||
+			InputFilter::get_singleton()->is_key_pressed(KEY_KP_ENTER) ||
+			InputFilter::get_singleton()->is_key_pressed(KEY_ENTER)) {
 
 
 		return;
 		return;
 	}
 	}
@@ -2531,7 +2531,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
 					range_drag_enabled = true;
 					range_drag_enabled = true;
 					range_drag_capture_pos = cpos;
 					range_drag_capture_pos = cpos;
 					range_drag_base = popup_edited_item->get_range(popup_edited_item_col);
 					range_drag_base = popup_edited_item->get_range(popup_edited_item_col);
-					Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
+					InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED);
 				}
 				}
 			} else {
 			} else {
 
 
@@ -2593,7 +2593,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
 					if (range_drag_enabled) {
 					if (range_drag_enabled) {
 
 
 						range_drag_enabled = false;
 						range_drag_enabled = false;
-						Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+						InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
 						warp_mouse(range_drag_capture_pos);
 						warp_mouse(range_drag_capture_pos);
 					} else {
 					} else {
 						Rect2 rect = get_selected()->get_meta("__focus_rect");
 						Rect2 rect = get_selected()->get_meta("__focus_rect");
@@ -3234,7 +3234,7 @@ void Tree::clear() {
 	if (pressing_for_editor) {
 	if (pressing_for_editor) {
 		if (range_drag_enabled) {
 		if (range_drag_enabled) {
 			range_drag_enabled = false;
 			range_drag_enabled = false;
-			Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+			InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
 			warp_mouse(range_drag_capture_pos);
 			warp_mouse(range_drag_capture_pos);
 		}
 		}
 		pressing_for_editor = false;
 		pressing_for_editor = false;

+ 1 - 2
scene/main/node.cpp

@@ -2950,9 +2950,8 @@ void Node::_bind_methods() {
 	BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT);
 	BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT);
 	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN);
 	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN);
 	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT);
 	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT);
-	BIND_CONSTANT(NOTIFICATION_WM_QUIT_REQUEST);
+	BIND_CONSTANT(NOTIFICATION_WM_CLOSE_REQUEST);
 	BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST);
 	BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST);
-	BIND_CONSTANT(NOTIFICATION_WM_UNFOCUS_REQUEST);
 	BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
 	BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
 	BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
 	BIND_CONSTANT(NOTIFICATION_WM_ABOUT);

+ 8 - 7
scene/main/node.h

@@ -244,13 +244,14 @@ public:
 		NOTIFICATION_INTERNAL_PHYSICS_PROCESS = 26,
 		NOTIFICATION_INTERNAL_PHYSICS_PROCESS = 26,
 		NOTIFICATION_POST_ENTER_TREE = 27,
 		NOTIFICATION_POST_ENTER_TREE = 27,
 		//keep these linked to node
 		//keep these linked to node
-		NOTIFICATION_WM_MOUSE_ENTER = MainLoop::NOTIFICATION_WM_MOUSE_ENTER,
-		NOTIFICATION_WM_MOUSE_EXIT = MainLoop::NOTIFICATION_WM_MOUSE_EXIT,
-		NOTIFICATION_WM_FOCUS_IN = MainLoop::NOTIFICATION_WM_FOCUS_IN,
-		NOTIFICATION_WM_FOCUS_OUT = MainLoop::NOTIFICATION_WM_FOCUS_OUT,
-		NOTIFICATION_WM_QUIT_REQUEST = MainLoop::NOTIFICATION_WM_QUIT_REQUEST,
-		NOTIFICATION_WM_GO_BACK_REQUEST = MainLoop::NOTIFICATION_WM_GO_BACK_REQUEST,
-		NOTIFICATION_WM_UNFOCUS_REQUEST = MainLoop::NOTIFICATION_WM_UNFOCUS_REQUEST,
+
+		NOTIFICATION_WM_MOUSE_ENTER = 1002,
+		NOTIFICATION_WM_MOUSE_EXIT = 1003,
+		NOTIFICATION_WM_FOCUS_IN = 1004,
+		NOTIFICATION_WM_FOCUS_OUT = 1005,
+		NOTIFICATION_WM_CLOSE_REQUEST = 1006,
+		NOTIFICATION_WM_GO_BACK_REQUEST = 1007,
+
 		NOTIFICATION_OS_MEMORY_WARNING = MainLoop::NOTIFICATION_OS_MEMORY_WARNING,
 		NOTIFICATION_OS_MEMORY_WARNING = MainLoop::NOTIFICATION_OS_MEMORY_WARNING,
 		NOTIFICATION_TRANSLATION_CHANGED = MainLoop::NOTIFICATION_TRANSLATION_CHANGED,
 		NOTIFICATION_TRANSLATION_CHANGED = MainLoop::NOTIFICATION_TRANSLATION_CHANGED,
 		NOTIFICATION_WM_ABOUT = MainLoop::NOTIFICATION_WM_ABOUT,
 		NOTIFICATION_WM_ABOUT = MainLoop::NOTIFICATION_WM_ABOUT,

+ 50 - 143
scene/main/scene_tree.cpp

@@ -31,7 +31,7 @@
 #include "scene_tree.h"
 #include "scene_tree.h"
 
 
 #include "core/debugger/engine_debugger.h"
 #include "core/debugger/engine_debugger.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/io/marshalls.h"
 #include "core/io/marshalls.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/message_queue.h"
 #include "core/message_queue.h"
@@ -398,69 +398,6 @@ void SceneTree::set_group(const StringName &p_group, const String &p_name, const
 	set_group_flags(0, p_group, p_name, p_value);
 	set_group_flags(0, p_group, p_name, p_value);
 }
 }
 
 
-void SceneTree::set_input_as_handled() {
-
-	input_handled = true;
-}
-
-void SceneTree::input_text(const String &p_text) {
-
-	root_lock++;
-
-	call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_vp_input_text", p_text); //special one for GUI, as controls use their own process check
-
-	root_lock--;
-}
-
-bool SceneTree::is_input_handled() {
-	return input_handled;
-}
-
-void SceneTree::input_event(const Ref<InputEvent> &p_event) {
-
-	if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_event.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_event)))
-		return; //avoid joy input on editor
-
-	current_event++;
-	root_lock++;
-
-	input_handled = false;
-
-	// Don't make const ref unless you can find and fix what caused GH-34691.
-	Ref<InputEvent> ev = p_event;
-
-	MainLoop::input_event(ev);
-
-	call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_vp_input", ev); //special one for GUI, as controls use their own process check
-
-	if (EngineDebugger::is_active()) {
-		//quit from game window using F8
-		Ref<InputEventKey> k = ev;
-		if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == KEY_F8) {
-			EngineDebugger::get_singleton()->send_message("request_quit", Array());
-		}
-	}
-
-	_flush_ugc();
-	root_lock--;
-	//MessageQueue::get_singleton()->flush(); //flushing here causes UI and other places slowness
-
-	root_lock++;
-
-	if (!input_handled) {
-		call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_vp_unhandled_input", ev); //special one for GUI, as controls use their own process check
-		_flush_ugc();
-		//		input_handled = true; - no reason to set this as handled
-		root_lock--;
-		//MessageQueue::get_singleton()->flush(); //flushing here causes UI and other places slowness
-	} else {
-		//		input_handled = true; - no reason to set this as handled
-		root_lock--;
-	}
-
-	_call_idle_callbacks();
-}
-
 void SceneTree::init() {
 void SceneTree::init() {
 	initialized = true;
 	initialized = true;
 	root->_set_tree(this);
 	root->_set_tree(this);
@@ -626,59 +563,36 @@ void SceneTree::quit(int p_exit_code) {
 	_quit = true;
 	_quit = true;
 }
 }
 
 
-void SceneTree::_notification(int p_notification) {
-
-	switch (p_notification) {
-
-		case NOTIFICATION_WM_QUIT_REQUEST: {
-
-			get_root()->propagate_notification(p_notification);
-
-			if (accept_quit) {
-				_quit = true;
-				break;
-			}
-		} break;
-
-		case NOTIFICATION_WM_GO_BACK_REQUEST: {
-
-			get_root()->propagate_notification(p_notification);
+void SceneTree::_main_window_close() {
 
 
-			if (quit_on_go_back) {
-				_quit = true;
-				break;
-			}
-		} break;
+	if (accept_quit) {
+		_quit = true;
+	}
+}
+void SceneTree::_main_window_go_back() {
+	if (quit_on_go_back) {
+		_quit = true;
+	}
+}
 
 
-		case NOTIFICATION_WM_FOCUS_IN: {
+void SceneTree::_main_window_focus_in() {
+	InputFilter *id = InputFilter::get_singleton();
+	if (id) {
+		id->ensure_touch_mouse_raised();
+	}
+}
 
 
-			Input *id = Input::get_singleton();
-			if (id) {
-				id->ensure_touch_mouse_raised();
-			}
+void SceneTree::_notification(int p_notification) {
 
 
-			get_root()->propagate_notification(p_notification);
-		} break;
+	switch (p_notification) {
 
 
 		case NOTIFICATION_TRANSLATION_CHANGED: {
 		case NOTIFICATION_TRANSLATION_CHANGED: {
 			if (!Engine::get_singleton()->is_editor_hint()) {
 			if (!Engine::get_singleton()->is_editor_hint()) {
 				get_root()->propagate_notification(p_notification);
 				get_root()->propagate_notification(p_notification);
 			}
 			}
 		} break;
 		} break;
-
-		case NOTIFICATION_WM_UNFOCUS_REQUEST: {
-
-			notify_group_flags(GROUP_CALL_REALTIME | GROUP_CALL_MULTILEVEL, "input", NOTIFICATION_WM_UNFOCUS_REQUEST);
-
-			get_root()->propagate_notification(p_notification);
-
-		} break;
-
 		case NOTIFICATION_OS_MEMORY_WARNING:
 		case NOTIFICATION_OS_MEMORY_WARNING:
 		case NOTIFICATION_OS_IME_UPDATE:
 		case NOTIFICATION_OS_IME_UPDATE:
-		case NOTIFICATION_WM_MOUSE_ENTER:
-		case NOTIFICATION_WM_MOUSE_EXIT:
-		case NOTIFICATION_WM_FOCUS_OUT:
 		case NOTIFICATION_WM_ABOUT:
 		case NOTIFICATION_WM_ABOUT:
 		case NOTIFICATION_CRASH:
 		case NOTIFICATION_CRASH:
 		case NOTIFICATION_APP_RESUMED:
 		case NOTIFICATION_APP_RESUMED:
@@ -894,7 +808,7 @@ bool SceneTree::is_paused() const {
 	return pause;
 	return pause;
 }
 }
 
 
-void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input) {
+void SceneTree::_notify_group_pause(const StringName &p_group, int p_notification) {
 
 
 	Map<StringName, Group>::Element *E = group_map.find(p_group);
 	Map<StringName, Group>::Element *E = group_map.find(p_group);
 	if (!E)
 	if (!E)
@@ -903,7 +817,7 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
 	if (g.nodes.empty())
 	if (g.nodes.empty())
 		return;
 		return;
 
 
-	_update_group_order(g);
+	_update_group_order(g, p_notification == Node::NOTIFICATION_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PROCESS || p_notification == Node::NOTIFICATION_PHYSICS_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 
 
 	//copy, so copy on write happens in case something is removed from process while being called
 	//copy, so copy on write happens in case something is removed from process while being called
 	//performance is not lost because only if something is added/removed the vector is copied.
 	//performance is not lost because only if something is added/removed the vector is copied.
@@ -912,15 +826,9 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
 	int node_count = nodes_copy.size();
 	int node_count = nodes_copy.size();
 	Node **nodes = nodes_copy.ptrw();
 	Node **nodes = nodes_copy.ptrw();
 
 
-	Variant arg = p_input;
-	const Variant *v[1] = { &arg };
-
 	call_lock++;
 	call_lock++;
 
 
-	for (int i = node_count - 1; i >= 0; i--) {
-
-		if (input_handled)
-			break;
+	for (int i = 0; i < node_count; i++) {
 
 
 		Node *n = nodes[i];
 		Node *n = nodes[i];
 		if (call_lock && call_skip.has(n))
 		if (call_lock && call_skip.has(n))
@@ -928,8 +836,10 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
 
 
 		if (!n->can_process())
 		if (!n->can_process())
 			continue;
 			continue;
+		if (!n->can_process_notification(p_notification))
+			continue;
 
 
-		n->call_multilevel(p_method, (const Variant **)v, 1);
+		n->notification(p_notification);
 		//ERR_FAIL_COND(node_count != g.nodes.size());
 		//ERR_FAIL_COND(node_count != g.nodes.size());
 	}
 	}
 
 
@@ -938,7 +848,18 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
 		call_skip.clear();
 		call_skip.clear();
 }
 }
 
 
-void SceneTree::_notify_group_pause(const StringName &p_group, int p_notification) {
+/*
+void SceneMainLoop::_update_listener_2d() {
+
+	if (listener_2d.is_valid()) {
+
+		SpatialSound2DServer::get_singleton()->listener_set_space( listener_2d, world_2d->get_sound_space() );
+	}
+
+}
+*/
+
+void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input, Viewport *p_viewport) {
 
 
 	Map<StringName, Group>::Element *E = group_map.find(p_group);
 	Map<StringName, Group>::Element *E = group_map.find(p_group);
 	if (!E)
 	if (!E)
@@ -947,7 +868,7 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
 	if (g.nodes.empty())
 	if (g.nodes.empty())
 		return;
 		return;
 
 
-	_update_group_order(g, p_notification == Node::NOTIFICATION_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PROCESS || p_notification == Node::NOTIFICATION_PHYSICS_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
+	_update_group_order(g);
 
 
 	//copy, so copy on write happens in case something is removed from process while being called
 	//copy, so copy on write happens in case something is removed from process while being called
 	//performance is not lost because only if something is added/removed the vector is copied.
 	//performance is not lost because only if something is added/removed the vector is copied.
@@ -956,9 +877,15 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
 	int node_count = nodes_copy.size();
 	int node_count = nodes_copy.size();
 	Node **nodes = nodes_copy.ptrw();
 	Node **nodes = nodes_copy.ptrw();
 
 
+	Variant arg = p_input;
+	const Variant *v[1] = { &arg };
+
 	call_lock++;
 	call_lock++;
 
 
-	for (int i = 0; i < node_count; i++) {
+	for (int i = node_count - 1; i >= 0; i--) {
+
+		if (p_viewport->is_input_handled())
+			break;
 
 
 		Node *n = nodes[i];
 		Node *n = nodes[i];
 		if (call_lock && call_skip.has(n))
 		if (call_lock && call_skip.has(n))
@@ -966,10 +893,8 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
 
 
 		if (!n->can_process())
 		if (!n->can_process())
 			continue;
 			continue;
-		if (!n->can_process_notification(p_notification))
-			continue;
 
 
-		n->notification(p_notification);
+		n->call_multilevel(p_method, (const Variant **)v, 1);
 		//ERR_FAIL_COND(node_count != g.nodes.size());
 		//ERR_FAIL_COND(node_count != g.nodes.size());
 	}
 	}
 
 
@@ -977,18 +902,6 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
 	if (call_lock == 0)
 	if (call_lock == 0)
 		call_skip.clear();
 		call_skip.clear();
 }
 }
-
-/*
-void SceneMainLoop::_update_listener_2d() {
-
-	if (listener_2d.is_valid()) {
-
-		SpatialSound2DServer::get_singleton()->listener_set_space( listener_2d, world_2d->get_sound_space() );
-	}
-
-}
-*/
-
 Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 
 
 	r_error.error = Callable::CallError::CALL_OK;
 	r_error.error = Callable::CallError::CALL_OK;
@@ -1191,12 +1104,6 @@ void SceneTree::add_current_scene(Node *p_current) {
 	root->add_child(p_current);
 	root->add_child(p_current);
 }
 }
 
 
-void SceneTree::drop_files(const Vector<String> &p_files, int p_from_screen) {
-
-	emit_signal("files_dropped", p_files, p_from_screen);
-	MainLoop::drop_files(p_files, p_from_screen);
-}
-
 void SceneTree::global_menu_action(const Variant &p_id, const Variant &p_meta) {
 void SceneTree::global_menu_action(const Variant &p_id, const Variant &p_meta) {
 
 
 	emit_signal("global_menu_action", p_id, p_meta);
 	emit_signal("global_menu_action", p_id, p_meta);
@@ -1330,8 +1237,6 @@ void SceneTree::_bind_methods() {
 
 
 	ClassDB::bind_method(D_METHOD("set_pause", "enable"), &SceneTree::set_pause);
 	ClassDB::bind_method(D_METHOD("set_pause", "enable"), &SceneTree::set_pause);
 	ClassDB::bind_method(D_METHOD("is_paused"), &SceneTree::is_paused);
 	ClassDB::bind_method(D_METHOD("is_paused"), &SceneTree::is_paused);
-	ClassDB::bind_method(D_METHOD("set_input_as_handled"), &SceneTree::set_input_as_handled);
-	ClassDB::bind_method(D_METHOD("is_input_handled"), &SceneTree::is_input_handled);
 
 
 	ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "pause_mode_process"), &SceneTree::create_timer, DEFVAL(true));
 	ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "pause_mode_process"), &SceneTree::create_timer, DEFVAL(true));
 
 
@@ -1495,7 +1400,6 @@ SceneTree::SceneTree() {
 	idle_process_time = 1;
 	idle_process_time = 1;
 
 
 	root = NULL;
 	root = NULL;
-	input_handled = false;
 	pause = false;
 	pause = false;
 	current_frame = 0;
 	current_frame = 0;
 	current_event = 0;
 	current_event = 0;
@@ -1512,7 +1416,6 @@ SceneTree::SceneTree() {
 
 
 	root = memnew(Window);
 	root = memnew(Window);
 	root->set_name("root");
 	root->set_name("root");
-	root->set_handle_input_locally(false);
 	if (!root->get_world().is_valid())
 	if (!root->get_world().is_valid())
 		root->set_world(Ref<World>(memnew(World)));
 		root->set_world(Ref<World>(memnew(World)));
 
 
@@ -1562,6 +1465,10 @@ SceneTree::SceneTree() {
 
 
 	root->set_physics_object_picking(GLOBAL_DEF("physics/common/enable_object_picking", true));
 	root->set_physics_object_picking(GLOBAL_DEF("physics/common/enable_object_picking", true));
 
 
+	root->connect("close_requested", callable_mp(this, &SceneTree::_main_window_close));
+	root->connect("go_back_requested", callable_mp(this, &SceneTree::_main_window_go_back));
+	root->connect("focus_entered", callable_mp(this, &SceneTree::_main_window_focus_in));
+
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 	edited_scene_root = NULL;
 	edited_scene_root = NULL;
 #endif
 #endif

+ 7 - 7
scene/main/scene_tree.h

@@ -105,7 +105,6 @@ private:
 	Map<StringName, Group> group_map;
 	Map<StringName, Group> group_map;
 	bool _quit;
 	bool _quit;
 	bool initialized;
 	bool initialized;
-	bool input_handled;
 
 
 	StringName tree_changed_name;
 	StringName tree_changed_name;
 	StringName node_added_name;
 	StringName node_added_name;
@@ -184,7 +183,6 @@ private:
 	void make_group_changed(const StringName &p_group);
 	void make_group_changed(const StringName &p_group);
 
 
 	void _notify_group_pause(const StringName &p_group, int p_notification);
 	void _notify_group_pause(const StringName &p_group, int p_notification);
-	void _call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input);
 	Variant _call_group_flags(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 	Variant _call_group_flags(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 	Variant _call_group(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 	Variant _call_group(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 
 
@@ -208,6 +206,13 @@ private:
 	static int idle_callback_count;
 	static int idle_callback_count;
 	void _call_idle_callbacks();
 	void _call_idle_callbacks();
 
 
+	void _main_window_focus_in();
+	void _main_window_close();
+	void _main_window_go_back();
+
+	//used by viewport
+	void _call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input, Viewport *p_viewport);
+
 protected:
 protected:
 	void _notification(int p_notification);
 	void _notification(int p_notification);
 	static void _bind_methods();
 	static void _bind_methods();
@@ -237,8 +242,6 @@ public:
 
 
 	void flush_transform_notifications();
 	void flush_transform_notifications();
 
 
-	virtual void input_text(const String &p_text);
-	virtual void input_event(const Ref<InputEvent> &p_event);
 	virtual void init();
 	virtual void init();
 
 
 	virtual bool iteration(float p_time);
 	virtual bool iteration(float p_time);
@@ -251,8 +254,6 @@ public:
 
 
 	void quit(int p_exit_code = -1);
 	void quit(int p_exit_code = -1);
 
 
-	void set_input_as_handled();
-	bool is_input_handled();
 	_FORCE_INLINE_ float get_physics_process_time() const { return physics_process_time; }
 	_FORCE_INLINE_ float get_physics_process_time() const { return physics_process_time; }
 	_FORCE_INLINE_ float get_idle_process_time() const { return idle_process_time; }
 	_FORCE_INLINE_ float get_idle_process_time() const { return idle_process_time; }
 
 
@@ -330,7 +331,6 @@ public:
 
 
 	static SceneTree *get_singleton() { return singleton; }
 	static SceneTree *get_singleton() { return singleton; }
 
 
-	void drop_files(const Vector<String> &p_files, int p_from_screen = 0);
 	void global_menu_action(const Variant &p_id, const Variant &p_meta);
 	void global_menu_action(const Variant &p_id, const Variant &p_meta);
 	void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
 	void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
 
 

+ 84 - 94
scene/main/viewport.cpp

@@ -32,7 +32,7 @@
 
 
 #include "core/core_string_names.h"
 #include "core/core_string_names.h"
 #include "core/debugger/engine_debugger.h"
 #include "core/debugger/engine_debugger.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 #include "scene/2d/collision_object_2d.h"
 #include "scene/2d/collision_object_2d.h"
@@ -49,6 +49,7 @@
 #include "scene/gui/popup_menu.h"
 #include "scene/gui/popup_menu.h"
 #include "scene/main/canvas_layer.h"
 #include "scene/main/canvas_layer.h"
 #include "scene/main/timer.h"
 #include "scene/main/timer.h"
+#include "scene/main/window.h"
 #include "scene/resources/mesh.h"
 #include "scene/resources/mesh.h"
 #include "scene/scene_string_names.h"
 #include "scene/scene_string_names.h"
 #include "servers/display_server.h"
 #include "servers/display_server.h"
@@ -394,7 +395,7 @@ void Viewport::_notification(int p_what) {
 				VS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count);
 				VS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count);
 			}
 			}
 
 
-			if (physics_object_picking && (to_screen_rect == Rect2i() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) {
+			if (physics_object_picking && (to_screen_rect == Rect2i() || InputFilter::get_singleton()->get_mouse_mode() != InputFilter::MOUSE_MODE_CAPTURED)) {
 
 
 #ifndef _3D_DISABLED
 #ifndef _3D_DISABLED
 				Vector2 last_pos(1e20, 1e20);
 				Vector2 last_pos(1e20, 1e20);
@@ -666,8 +667,8 @@ void Viewport::_notification(int p_what) {
 			}
 			}
 
 
 		} break;
 		} break;
-		case SceneTree::NOTIFICATION_WM_MOUSE_EXIT:
-		case SceneTree::NOTIFICATION_WM_FOCUS_OUT: {
+		case NOTIFICATION_WM_MOUSE_EXIT:
+		case NOTIFICATION_WM_FOCUS_OUT: {
 
 
 			_drop_physics_mouseover();
 			_drop_physics_mouseover();
 
 
@@ -1333,76 +1334,15 @@ Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) {
 	return ev->xformed_by(ai, -vp_ofs);
 	return ev->xformed_by(ai, -vp_ofs);
 }
 }
 
 
-void Viewport::_vp_input_text(const String &p_text) {
-
-	if (gui.key_focus) {
-		gui.key_focus->call("set_text", p_text);
-	}
-}
-
-void Viewport::_vp_input(const Ref<InputEvent> &p_ev) {
-
-	if (disable_input)
-		return;
-
-#ifdef TOOLS_ENABLED
-	if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) {
-		return;
-	}
-#endif
-
-	Ref<InputEventFromWindow> window_event = p_ev;
-	if (window_event.is_valid()) {
-		if (window_event->get_window_id() != get_window_id()) {
-			return;
-		}
-	}
-
-	//this one handles system input, p_ev are in system coordinates
-	//they are converted to viewport coordinates
-
-	Ref<InputEvent> ev = _make_input_local(p_ev);
-	input(ev);
-}
-
-void Viewport::_vp_unhandled_input(const Ref<InputEvent> &p_ev) {
-
-	if (disable_input)
-		return;
-#ifdef TOOLS_ENABLED
-	if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) {
-		return;
-	}
-#endif
-
-	/*
-	if (parent_control && !parent_control->is_visible_in_tree())
-		return;
-	*/
-
-	Ref<InputEventFromWindow> window_event = p_ev;
-	if (window_event.is_valid()) {
-		if (window_event->get_window_id() != get_window_id()) {
-			return;
-		}
-	}
-
-	//this one handles system input, p_ev are in system coordinates
-	//they are converted to viewport coordinates
-
-	Ref<InputEvent> ev = _make_input_local(p_ev);
-	unhandled_input(ev);
-}
-
 Vector2 Viewport::get_mouse_position() const {
 Vector2 Viewport::get_mouse_position() const {
 
 
-	return (get_final_transform().affine_inverse() * _get_input_pre_xform()).xform(Input::get_singleton()->get_mouse_position() - _get_window_offset());
+	return (get_final_transform().affine_inverse() * _get_input_pre_xform()).xform(InputFilter::get_singleton()->get_mouse_position() - _get_window_offset());
 }
 }
 
 
 void Viewport::warp_mouse(const Vector2 &p_pos) {
 void Viewport::warp_mouse(const Vector2 &p_pos) {
 
 
 	Vector2 gpos = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse().xform(p_pos);
 	Vector2 gpos = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse().xform(p_pos);
-	Input::get_singleton()->warp_mouse_position(gpos);
+	InputFilter::get_singleton()->warp_mouse_position(gpos);
 }
 }
 
 
 void Viewport::_gui_prepare_subwindows() {
 void Viewport::_gui_prepare_subwindows() {
@@ -2109,7 +2049,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 		}
 		}
 
 
 		if (!over) {
 		if (!over) {
-			DisplayServer::get_singleton()->cursor_set_shape((DisplayServer::CursorShape)Input::get_singleton()->get_default_cursor_shape());
+			DisplayServer::get_singleton()->cursor_set_shape((DisplayServer::CursorShape)InputFilter::get_singleton()->get_default_cursor_shape());
 			return;
 			return;
 		}
 		}
 
 
@@ -2363,7 +2303,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 		if (from && p_event->is_pressed()) {
 		if (from && p_event->is_pressed()) {
 			Control *next = NULL;
 			Control *next = NULL;
 
 
-			Input *input = Input::get_singleton();
+			InputFilter *input = InputFilter::get_singleton();
 
 
 			if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) {
 			if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) {
 
 
@@ -2735,44 +2675,78 @@ void Viewport::_post_gui_grab_click_focus() {
 
 
 ///////////////////////////////
 ///////////////////////////////
 
 
-void Viewport::input(const Ref<InputEvent> &p_event) {
+void Viewport::input_text(const String &p_text) {
+
+	if (gui.key_focus) {
+		gui.key_focus->call("set_text", p_text);
+	}
+}
+void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
 
 
 	ERR_FAIL_COND(!is_inside_tree());
 	ERR_FAIL_COND(!is_inside_tree());
 
 
+	if (disable_input)
+		return;
+
+	if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) {
+		return;
+	}
+
 	local_input_handled = false;
 	local_input_handled = false;
 
 
+	Ref<InputEvent> ev;
+	if (!p_local_coords) {
+		ev = _make_input_local(p_event);
+	} else {
+		ev = p_event;
+	}
+
 	if (!is_input_handled()) {
 	if (!is_input_handled()) {
-		get_tree()->_call_input_pause(input_group, "_input", p_event); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
+		get_tree()->_call_input_pause(input_group, "_input", ev, this); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
 	}
 	}
 
 
 	if (!is_input_handled()) {
 	if (!is_input_handled()) {
-		_gui_input_event(p_event);
+		_gui_input_event(ev);
 	}
 	}
-	//get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",p_event); //special one for GUI, as controls use their own process check
+	//get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",ev); //special one for GUI, as controls use their own process check
 }
 }
 
 
-void Viewport::unhandled_input(const Ref<InputEvent> &p_event) {
+void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
 
 
 	ERR_FAIL_COND(!is_inside_tree());
 	ERR_FAIL_COND(!is_inside_tree());
 
 
-	get_tree()->_call_input_pause(unhandled_input_group, "_unhandled_input", p_event);
+	if (disable_input)
+		return;
+
+	if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) {
+		return;
+	}
+
+	Ref<InputEvent> ev;
+	if (!p_local_coords) {
+		ev = _make_input_local(p_event);
+	} else {
+		ev = p_event;
+	}
+
+	get_tree()->_call_input_pause(unhandled_input_group, "_unhandled_input", ev, this);
 	//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev);
 	//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev);
-	if (!get_tree()->input_handled && Object::cast_to<InputEventKey>(*p_event) != NULL) {
-		get_tree()->_call_input_pause(unhandled_key_input_group, "_unhandled_key_input", p_event);
+	if (!is_input_handled() && Object::cast_to<InputEventKey>(*ev) != NULL) {
+		get_tree()->_call_input_pause(unhandled_key_input_group, "_unhandled_key_input", ev, this);
 		//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev);
 		//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev);
 	}
 	}
 
 
-	if (physics_object_picking && !get_tree()->input_handled) {
+	if (physics_object_picking && !is_input_handled()) {
 
 
-		if (Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED &&
-				(Object::cast_to<InputEventMouseButton>(*p_event) ||
-						Object::cast_to<InputEventMouseMotion>(*p_event) ||
-						Object::cast_to<InputEventScreenDrag>(*p_event) ||
-						Object::cast_to<InputEventScreenTouch>(*p_event) ||
-						Object::cast_to<InputEventKey>(*p_event) //to remember state
+		if (InputFilter::get_singleton()->get_mouse_mode() != InputFilter::MOUSE_MODE_CAPTURED &&
+				(Object::cast_to<InputEventMouseButton>(*ev) ||
+						Object::cast_to<InputEventMouseMotion>(*ev) ||
+						Object::cast_to<InputEventScreenDrag>(*ev) ||
+						Object::cast_to<InputEventScreenTouch>(*ev) ||
+						Object::cast_to<InputEventKey>(*ev) //to remember state
 
 
 						)) {
 						)) {
-			physics_picking_events.push_back(p_event);
+			physics_picking_events.push_back(ev);
 		}
 		}
 	}
 	}
 }
 }
@@ -2930,7 +2904,17 @@ void Viewport::set_input_as_handled() {
 		local_input_handled = true;
 		local_input_handled = true;
 	} else {
 	} else {
 		ERR_FAIL_COND(!is_inside_tree());
 		ERR_FAIL_COND(!is_inside_tree());
-		get_tree()->set_input_as_handled();
+		Viewport *vp = this;
+		while (true) {
+			if (Object::cast_to<Window>(vp)) {
+				break;
+			}
+			if (!vp->get_parent()) {
+				break;
+			}
+			vp = vp->get_parent()->get_viewport();
+		}
+		vp->set_input_as_handled();
 	}
 	}
 }
 }
 
 
@@ -2938,8 +2922,17 @@ bool Viewport::is_input_handled() const {
 	if (handle_input_locally) {
 	if (handle_input_locally) {
 		return local_input_handled;
 		return local_input_handled;
 	} else {
 	} else {
-		ERR_FAIL_COND_V(!is_inside_tree(), false);
-		return get_tree()->is_input_handled();
+		const Viewport *vp = this;
+		while (true) {
+			if (Object::cast_to<Window>(vp)) {
+				break;
+			}
+			if (!vp->get_parent()) {
+				break;
+			}
+			vp = vp->get_parent()->get_viewport();
+		}
+		return vp->is_input_handled();
 	}
 	}
 }
 }
 
 
@@ -3042,10 +3035,6 @@ void Viewport::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_transparent_background", "enable"), &Viewport::set_transparent_background);
 	ClassDB::bind_method(D_METHOD("set_transparent_background", "enable"), &Viewport::set_transparent_background);
 	ClassDB::bind_method(D_METHOD("has_transparent_background"), &Viewport::has_transparent_background);
 	ClassDB::bind_method(D_METHOD("has_transparent_background"), &Viewport::has_transparent_background);
 
 
-	ClassDB::bind_method(D_METHOD("_vp_input"), &Viewport::_vp_input);
-	ClassDB::bind_method(D_METHOD("_vp_input_text", "text"), &Viewport::_vp_input_text);
-	ClassDB::bind_method(D_METHOD("_vp_unhandled_input"), &Viewport::_vp_unhandled_input);
-
 	ClassDB::bind_method(D_METHOD("set_msaa", "msaa"), &Viewport::set_msaa);
 	ClassDB::bind_method(D_METHOD("set_msaa", "msaa"), &Viewport::set_msaa);
 	ClassDB::bind_method(D_METHOD("get_msaa"), &Viewport::get_msaa);
 	ClassDB::bind_method(D_METHOD("get_msaa"), &Viewport::get_msaa);
 
 
@@ -3060,8 +3049,9 @@ void Viewport::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking);
 	ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking);
 
 
 	ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid);
 	ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid);
-	ClassDB::bind_method(D_METHOD("input", "local_event"), &Viewport::input);
-	ClassDB::bind_method(D_METHOD("unhandled_input", "local_event"), &Viewport::unhandled_input);
+	ClassDB::bind_method(D_METHOD("input_text", "text"), &Viewport::input_text);
+	ClassDB::bind_method(D_METHOD("input", "event", "in_local_coords"), &Viewport::input, DEFVAL(false));
+	ClassDB::bind_method(D_METHOD("unhandled_input", "event", "in_local_coords"), &Viewport::unhandled_input, DEFVAL(false));
 
 
 	ClassDB::bind_method(D_METHOD("update_worlds"), &Viewport::update_worlds);
 	ClassDB::bind_method(D_METHOD("update_worlds"), &Viewport::update_worlds);
 
 

+ 3 - 5
scene/main/viewport.h

@@ -329,9 +329,6 @@ private:
 
 
 	_FORCE_INLINE_ Transform2D _get_input_pre_xform() const;
 	_FORCE_INLINE_ Transform2D _get_input_pre_xform() const;
 
 
-	void _vp_input(const Ref<InputEvent> &p_ev);
-	void _vp_input_text(const String &p_text);
-	void _vp_unhandled_input(const Ref<InputEvent> &p_ev);
 	Ref<InputEvent> _make_input_local(const Ref<InputEvent> &ev);
 	Ref<InputEvent> _make_input_local(const Ref<InputEvent> &ev);
 
 
 	friend class Control;
 	friend class Control;
@@ -475,8 +472,9 @@ public:
 	void set_use_own_world(bool p_world);
 	void set_use_own_world(bool p_world);
 	bool is_using_own_world() const;
 	bool is_using_own_world() const;
 
 
-	void input(const Ref<InputEvent> &p_event);
-	void unhandled_input(const Ref<InputEvent> &p_event);
+	void input_text(const String &p_text);
+	void input(const Ref<InputEvent> &p_event, bool p_local_coords = false);
+	void unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords = false);
 
 
 	void set_disable_input(bool p_disable);
 	void set_disable_input(bool p_disable);
 	bool is_input_disabled() const;
 	bool is_input_disabled() const;

+ 87 - 3
scene/main/window.cpp

@@ -30,6 +30,8 @@
 
 
 #include "window.h"
 #include "window.h"
 
 
+#include "core/debugger/engine_debugger.h"
+#include "core/os/keyboard.h"
 #include "scene/resources/dynamic_font.h"
 #include "scene/resources/dynamic_font.h"
 
 
 void Window::set_title(const String &p_title) {
 void Window::set_title(const String &p_title) {
@@ -242,6 +244,48 @@ void Window::_resize_callback(const Size2i &p_callback) {
 	_update_size();
 	_update_size();
 }
 }
 
 
+void Window::_propagate_window_notification(Node *p_node, int p_notification) {
+	p_node->notification(p_notification);
+	for (int i = 0; i < p_node->get_child_count(); i++) {
+		Node *child = p_node->get_child(i);
+		Window *window = Object::cast_to<Window>(child);
+		if (window) {
+			break;
+		}
+		_propagate_window_notification(child, p_notification);
+	}
+}
+
+void Window::_event_callback(DisplayServer::WindowEvent p_event) {
+
+	switch (p_event) {
+		case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: {
+			_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER);
+			emit_signal("mouse_entered");
+		} break;
+		case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: {
+			_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_EXIT);
+			emit_signal("mouse_exited");
+		} break;
+		case DisplayServer::WINDOW_EVENT_FOCUS_IN: {
+			_propagate_window_notification(this, NOTIFICATION_WM_FOCUS_IN);
+			emit_signal("focus_entered");
+		} break;
+		case DisplayServer::WINDOW_EVENT_FOCUS_OUT: {
+			_propagate_window_notification(this, NOTIFICATION_WM_FOCUS_OUT);
+			emit_signal("focus_exited");
+		} break;
+		case DisplayServer::WINDOW_EVENT_CLOSE_REQUEST: {
+			_propagate_window_notification(this, NOTIFICATION_WM_CLOSE_REQUEST);
+			emit_signal("close_requested");
+		} break;
+		case DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST: {
+			_propagate_window_notification(this, NOTIFICATION_WM_GO_BACK_REQUEST);
+			emit_signal("go_back_requested");
+		} break;
+	}
+}
+
 void Window::set_visible(bool p_visible) {
 void Window::set_visible(bool p_visible) {
 	if (visible == p_visible) {
 	if (visible == p_visible) {
 		return;
 		return;
@@ -398,6 +442,13 @@ void Window::_update_size() {
 	}
 	}
 }
 }
 
 
+void Window::_update_window_callbacks() {
+	DisplayServer::get_singleton()->window_set_resize_callback(callable_mp(this, &Window::_resize_callback), window_id);
+	DisplayServer::get_singleton()->window_set_window_event_callback(callable_mp(this, &Window::_event_callback), window_id);
+	DisplayServer::get_singleton()->window_set_input_event_callback(callable_mp(this, &Window::_window_input), window_id);
+	DisplayServer::get_singleton()->window_set_input_text_callback(callable_mp(this, &Window::_window_input_text), window_id);
+	DisplayServer::get_singleton()->window_set_drop_files_callback(callable_mp(this, &Window::_window_drop_files), window_id);
+}
 void Window::_notification(int p_what) {
 void Window::_notification(int p_what) {
 	if (p_what == NOTIFICATION_ENTER_TREE) {
 	if (p_what == NOTIFICATION_ENTER_TREE) {
 		if (is_embedded()) {
 		if (is_embedded()) {
@@ -409,11 +460,11 @@ void Window::_notification(int p_what) {
 				window_id = DisplayServer::MAIN_WINDOW_ID;
 				window_id = DisplayServer::MAIN_WINDOW_ID;
 				_update_from_window();
 				_update_from_window();
 				_update_size();
 				_update_size();
-				DisplayServer::get_singleton()->window_set_resize_callback(callable_mp(this, &Window::_resize_callback), window_id);
+				_update_window_callbacks();
 			} else {
 			} else {
 				//create
 				//create
 				_make_window();
 				_make_window();
-				DisplayServer::get_singleton()->window_set_resize_callback(callable_mp(this, &Window::_resize_callback), window_id);
+				_update_window_callbacks();
 			}
 			}
 		}
 		}
 	}
 	}
@@ -423,7 +474,7 @@ void Window::_notification(int p_what) {
 
 
 			if (window_id == DisplayServer::MAIN_WINDOW_ID) {
 			if (window_id == DisplayServer::MAIN_WINDOW_ID) {
 
 
-				DisplayServer::get_singleton()->window_set_resize_callback(Callable(), window_id);
+				_update_window_callbacks();
 			} else {
 			} else {
 				_clear_window();
 				_clear_window();
 			}
 			}
@@ -475,7 +526,40 @@ DisplayServer::WindowID Window::get_window_id() const {
 	return window_id;
 	return window_id;
 }
 }
 
 
+void Window::_window_input(const Ref<InputEvent> &p_ev) {
+
+	if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev)))
+		return; //avoid joy input on editor
+
+	if (EngineDebugger::is_active()) {
+		//quit from game window using F8
+		Ref<InputEventKey> k = p_ev;
+		if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == KEY_F8) {
+			EngineDebugger::get_singleton()->send_message("request_quit", Array());
+		}
+	}
+
+	input(p_ev);
+	if (!is_input_handled()) {
+		unhandled_input(p_ev);
+	}
+}
+void Window::_window_input_text(const String &p_text) {
+	input_text(p_text);
+}
+void Window::_window_drop_files(const Vector<String> &p_files) {
+	emit_signal("files_dropped", p_files);
+}
+
 void Window::_bind_methods() {
 void Window::_bind_methods() {
+
+	ADD_SIGNAL(MethodInfo("files_dropped"));
+	ADD_SIGNAL(MethodInfo("mouse_entered"));
+	ADD_SIGNAL(MethodInfo("mouse_exited"));
+	ADD_SIGNAL(MethodInfo("focus_entered"));
+	ADD_SIGNAL(MethodInfo("focus_exited"));
+	ADD_SIGNAL(MethodInfo("close_requested"));
+	ADD_SIGNAL(MethodInfo("go_back_requested"));
 }
 }
 
 
 Window::Window() {
 Window::Window() {

+ 10 - 0
scene/main/window.h

@@ -95,11 +95,21 @@ private:
 	void _update_from_window();
 	void _update_from_window();
 
 
 	void _resize_callback(const Size2i &p_callback);
 	void _resize_callback(const Size2i &p_callback);
+	void _event_callback(DisplayServer::WindowEvent p_event);
 
 
 	void _update_size();
 	void _update_size();
 
 
+	void _propagate_window_notification(Node *p_node, int p_notification);
+
 	virtual DisplayServer::WindowID get_window_id() const;
 	virtual DisplayServer::WindowID get_window_id() const;
 
 
+	void _window_input(const Ref<InputEvent> &p_ev);
+	void _window_input_text(const String &p_text);
+	void _window_drop_files(const Vector<String> &p_files);
+
+	void _window_unhandled_input(const Ref<InputEvent> &p_ev);
+	void _update_window_callbacks();
+
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();
 	void _notification(int p_what);
 	void _notification(int p_what);

+ 4 - 0
scene/scene_string_names.cpp

@@ -193,6 +193,10 @@ SceneStringNames::SceneStringNames() {
 		mesh_materials[i] = "material/" + itos(i);
 		mesh_materials[i] = "material/" + itos(i);
 	}
 	}
 
 
+	_window_group = StaticCString::create("_window_group");
+	_window_input = StaticCString::create("_window_input");
+	_window_unhandled_input = StaticCString::create("_window_unhandled_input");
+
 	parameters_base_path = "parameters/";
 	parameters_base_path = "parameters/";
 
 
 	tracks_changed = "tracks_changed";
 	tracks_changed = "tracks_changed";

+ 4 - 0
scene/scene_string_names.h

@@ -201,6 +201,10 @@ public:
 
 
 	StringName tracks_changed;
 	StringName tracks_changed;
 
 
+	StringName _window_group;
+	StringName _window_input;
+	StringName _window_unhandled_input;
+
 	enum {
 	enum {
 		MAX_MATERIALS = 32
 		MAX_MATERIALS = 32
 	};
 	};

+ 1 - 1
servers/arvr/arvr_positional_tracker.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "arvr_positional_tracker.h"
 #include "arvr_positional_tracker.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 
 
 void ARVRPositionalTracker::_bind_methods() {
 void ARVRPositionalTracker::_bind_methods() {
 	BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN);
 	BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN);

+ 24 - 13
servers/display_server.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "display_server.h"
 #include "display_server.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 
 
 DisplayServer *DisplayServer::singleton = nullptr;
 DisplayServer *DisplayServer::singleton = nullptr;
 DisplayServer::SwitchVSyncCallbackInThread DisplayServer::switch_vsync_function = nullptr;
 DisplayServer::SwitchVSyncCallbackInThread DisplayServer::switch_vsync_function = nullptr;
@@ -83,7 +83,7 @@ DisplayServer::ScreenOrientation DisplayServer::screen_get_orientation(int p_scr
 
 
 bool DisplayServer::screen_is_touchscreen(int p_screen) const {
 bool DisplayServer::screen_is_touchscreen(int p_screen) const {
 	//return false;
 	//return false;
-	return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse();
+	return InputFilter::get_singleton() && InputFilter::get_singleton()->is_emulating_touch_from_mouse();
 }
 }
 
 
 void DisplayServer::screen_set_keep_on(bool p_enable) {
 void DisplayServer::screen_set_keep_on(bool p_enable) {
@@ -275,6 +275,10 @@ void DisplayServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("window_get_size", "window_id"), &DisplayServer::window_get_size, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_get_size", "window_id"), &DisplayServer::window_get_size, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_set_size", "size", "window_id"), &DisplayServer::window_set_size, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_set_size", "size", "window_id"), &DisplayServer::window_set_size, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_set_resize_callback", "callback", "window_id"), &DisplayServer::window_set_resize_callback, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_set_resize_callback", "callback", "window_id"), &DisplayServer::window_set_resize_callback, DEFVAL(MAIN_WINDOW_ID));
+	ClassDB::bind_method(D_METHOD("window_set_window_event_callback", "callback", "window_id"), &DisplayServer::window_set_window_event_callback, DEFVAL(MAIN_WINDOW_ID));
+	ClassDB::bind_method(D_METHOD("window_set_input_event_callback", "callback", "window_id"), &DisplayServer::window_set_input_event_callback, DEFVAL(MAIN_WINDOW_ID));
+	ClassDB::bind_method(D_METHOD("window_set_input_text_callback", "callback", "window_id"), &DisplayServer::window_set_input_text_callback, DEFVAL(MAIN_WINDOW_ID));
+	ClassDB::bind_method(D_METHOD("window_set_drop_files_callback", "callback", "window_id"), &DisplayServer::window_set_drop_files_callback, DEFVAL(MAIN_WINDOW_ID));
 
 
 	ClassDB::bind_method(D_METHOD("window_get_max_size", "window_id"), &DisplayServer::window_get_max_size, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_get_max_size", "window_id"), &DisplayServer::window_get_max_size, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_set_max_size", "max_size", "window_id"), &DisplayServer::window_set_max_size, DEFVAL(MAIN_WINDOW_ID));
 	ClassDB::bind_method(D_METHOD("window_set_max_size", "max_size", "window_id"), &DisplayServer::window_set_max_size, DEFVAL(MAIN_WINDOW_ID));
@@ -418,6 +422,13 @@ void DisplayServer::_bind_methods() {
 	BIND_ENUM_CONSTANT(LATIN_KEYBOARD_DVORAK);
 	BIND_ENUM_CONSTANT(LATIN_KEYBOARD_DVORAK);
 	BIND_ENUM_CONSTANT(LATIN_KEYBOARD_NEO);
 	BIND_ENUM_CONSTANT(LATIN_KEYBOARD_NEO);
 	BIND_ENUM_CONSTANT(LATIN_KEYBOARD_COLEMAK);
 	BIND_ENUM_CONSTANT(LATIN_KEYBOARD_COLEMAK);
+
+	BIND_ENUM_CONSTANT(WINDOW_EVENT_MOUSE_ENTER);
+	BIND_ENUM_CONSTANT(WINDOW_EVENT_MOUSE_EXIT);
+	BIND_ENUM_CONSTANT(WINDOW_EVENT_FOCUS_IN);
+	BIND_ENUM_CONSTANT(WINDOW_EVENT_FOCUS_OUT);
+	BIND_ENUM_CONSTANT(WINDOW_EVENT_CLOSE_REQUEST);
+	BIND_ENUM_CONSTANT(WINDOW_EVENT_GO_BACK_REQUEST);
 }
 }
 
 
 void DisplayServer::register_create_function(const char *p_name, CreateFunction p_function, GetVideoDriversFunction p_get_drivers) {
 void DisplayServer::register_create_function(const char *p_name, CreateFunction p_function, GetVideoDriversFunction p_get_drivers) {
@@ -444,31 +455,31 @@ DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driv
 	return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_flags, p_resolution, r_error);
 	return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_flags, p_resolution, r_error);
 }
 }
 
 
-void DisplayServer::_input_set_mouse_mode(Input::MouseMode p_mode) {
+void DisplayServer::_input_set_mouse_mode(InputFilter::MouseMode p_mode) {
 	singleton->mouse_set_mode(MouseMode(p_mode));
 	singleton->mouse_set_mode(MouseMode(p_mode));
 }
 }
-Input::MouseMode DisplayServer::_input_get_mouse_mode() {
-	return Input::MouseMode(singleton->mouse_get_mode());
+InputFilter::MouseMode DisplayServer::_input_get_mouse_mode() {
+	return InputFilter::MouseMode(singleton->mouse_get_mode());
 }
 }
 
 
 void DisplayServer::_input_warp(const Vector2 &p_to_pos) {
 void DisplayServer::_input_warp(const Vector2 &p_to_pos) {
 	singleton->mouse_warp_to_position(p_to_pos);
 	singleton->mouse_warp_to_position(p_to_pos);
 }
 }
 
 
-Input::CursorShape DisplayServer::_input_get_current_cursor_shape() {
-	return (Input::CursorShape)singleton->cursor_get_shape();
+InputFilter::CursorShape DisplayServer::_input_get_current_cursor_shape() {
+	return (InputFilter::CursorShape)singleton->cursor_get_shape();
 }
 }
-void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, Input::CursorShape p_shape, const Vector2 &p_hostspot) {
+void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, InputFilter::CursorShape p_shape, const Vector2 &p_hostspot) {
 	singleton->cursor_set_custom_image(p_image, (CursorShape)p_shape, p_hostspot);
 	singleton->cursor_set_custom_image(p_image, (CursorShape)p_shape, p_hostspot);
 }
 }
 
 
 DisplayServer::DisplayServer() {
 DisplayServer::DisplayServer() {
 	singleton = this;
 	singleton = this;
-	Input::set_mouse_mode_func = _input_set_mouse_mode;
-	Input::get_mouse_mode_func = _input_get_mouse_mode;
-	Input::warp_mouse_func = _input_warp;
-	Input::get_current_cursor_shape_func = _input_get_current_cursor_shape;
-	Input::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func;
+	InputFilter::set_mouse_mode_func = _input_set_mouse_mode;
+	InputFilter::get_mouse_mode_func = _input_get_mouse_mode;
+	InputFilter::warp_mouse_func = _input_warp;
+	InputFilter::get_current_cursor_shape_func = _input_get_current_cursor_shape;
+	InputFilter::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func;
 }
 }
 DisplayServer::~DisplayServer() {
 DisplayServer::~DisplayServer() {
 }
 }

+ 20 - 5
servers/display_server.h

@@ -32,7 +32,7 @@
 #define DISPLAY_SERVER_H
 #define DISPLAY_SERVER_H
 
 
 #include "core/callable.h"
 #include "core/callable.h"
-#include "core/input/input.h"
+#include "core/input/input_filter.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "core/resource.h"
 #include "core/resource.h"
 
 
@@ -56,11 +56,11 @@ public:
 	typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, uint32_t, const Size2i &, Error &r_error); //video driver, window mode, resolution
 	typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, uint32_t, const Size2i &, Error &r_error); //video driver, window mode, resolution
 	typedef Vector<String> (*GetVideoDriversFunction)(); //video driver, window mode, resolution
 	typedef Vector<String> (*GetVideoDriversFunction)(); //video driver, window mode, resolution
 private:
 private:
-	static void _input_set_mouse_mode(Input::MouseMode p_mode);
-	static Input::MouseMode _input_get_mouse_mode();
+	static void _input_set_mouse_mode(InputFilter::MouseMode p_mode);
+	static InputFilter::MouseMode _input_get_mouse_mode();
 	static void _input_warp(const Vector2 &p_to_pos);
 	static void _input_warp(const Vector2 &p_to_pos);
-	static Input::CursorShape _input_get_current_cursor_shape();
-	static void _input_set_custom_mouse_cursor_func(const RES &, Input::CursorShape, const Vector2 &p_hostspot);
+	static InputFilter::CursorShape _input_get_current_cursor_shape();
+	static void _input_set_custom_mouse_cursor_func(const RES &, InputFilter::CursorShape, const Vector2 &p_hostspot);
 
 
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();
@@ -182,6 +182,20 @@ public:
 	virtual void delete_sub_window(WindowID p_id);
 	virtual void delete_sub_window(WindowID p_id);
 
 
 	virtual void window_set_resize_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0;
 	virtual void window_set_resize_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0;
+
+	enum WindowEvent {
+		WINDOW_EVENT_MOUSE_ENTER,
+		WINDOW_EVENT_MOUSE_EXIT,
+		WINDOW_EVENT_FOCUS_IN,
+		WINDOW_EVENT_FOCUS_OUT,
+		WINDOW_EVENT_CLOSE_REQUEST,
+		WINDOW_EVENT_GO_BACK_REQUEST,
+	};
+	virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0;
+	virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0;
+	virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0;
+	virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0;
+
 	virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) = 0;
 	virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) = 0;
 
 
 	virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const = 0;
 	virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const = 0;
@@ -321,6 +335,7 @@ public:
 	~DisplayServer();
 	~DisplayServer();
 };
 };
 
 
+VARIANT_ENUM_CAST(DisplayServer::WindowEvent)
 VARIANT_ENUM_CAST(DisplayServer::Feature)
 VARIANT_ENUM_CAST(DisplayServer::Feature)
 VARIANT_ENUM_CAST(DisplayServer::MouseMode)
 VARIANT_ENUM_CAST(DisplayServer::MouseMode)
 VARIANT_ENUM_CAST(DisplayServer::ScreenOrientation)
 VARIANT_ENUM_CAST(DisplayServer::ScreenOrientation)