diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 91c34e2e1428..398aa050e53c 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -538,6 +538,12 @@ Default value for [member ScrollContainer.scroll_deadzone], which will be used for all [ScrollContainer]s unless overridden. + + If enabled, the moment [member Viewport.gui_disable_input] is set to [code]false[/code] to disable GUI input in a viewport, current mouse over and mouse focus will be dropped. + That behavior helps to keep a robust GUI state, with no surprises when input is resumed regardless what has happened in the meantime. + If disabled, the legacy behavior is used, which consists in just not doing anything besides the GUI input disable itself. + [b]Note:[/b] This is set to [code]true[/code] by default for new projects and is the recommended setting. + If [code]true[/code], swaps OK and Cancel buttons in dialogs on Windows and UWP to follow interface conventions. diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index ad42f8fc4aa8..4f32e2db3a78 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -470,6 +470,7 @@ class ProjectDialog : public ConfirmationDialog { initial_settings["application/config/icon"] = "res://icon.png"; initial_settings["rendering/environment/default_environment"] = "res://default_env.tres"; initial_settings["physics/common/enable_pause_aware_picking"] = true; + initial_settings["gui/common/drop_mouse_on_gui_input_disabled"] = true; if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("project.godot"), initial_settings, Vector(), false) != OK) { set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR); diff --git a/main/main.cpp b/main/main.cpp index ad802d01d551..5ab704467371 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1219,6 +1219,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Engine::get_singleton()->set_target_fps(GLOBAL_DEF("debug/settings/fps/force_fps", 0)); ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/fps/force_fps", PropertyInfo(Variant::INT, "debug/settings/fps/force_fps", PROPERTY_HINT_RANGE, "0,1000,1")); GLOBAL_DEF("physics/common/enable_pause_aware_picking", false); + GLOBAL_DEF("gui/common/drop_mouse_on_gui_input_disabled", false); GLOBAL_DEF("debug/settings/stdout/print_fps", false); GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 8edc0e39b55c..68e13b8c8962 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2058,9 +2058,7 @@ void Viewport::_gui_input_event(Ref p_event) { } if (gui.mouse_focus_mask == 0 && over != gui.mouse_over) { - if (gui.mouse_over) { - _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); - } + _drop_mouse_over(); _gui_cancel_tooltip(); @@ -2177,9 +2175,7 @@ void Viewport::_gui_input_event(Ref p_event) { } if (over != gui.mouse_over) { - if (gui.mouse_over) { - _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); - } + _drop_mouse_over(); _gui_cancel_tooltip(); @@ -2715,6 +2711,13 @@ void Viewport::_drop_mouse_focus() { } } +void Viewport::_drop_mouse_over() { + if (gui.mouse_over) { + _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT); + gui.mouse_over = nullptr; + } +} + void Viewport::_drop_physics_mouseover(bool p_paused_only) { physics_has_last_mousepos = false; @@ -2958,6 +2961,14 @@ bool Viewport::gui_has_modal_stack() const { } void Viewport::set_disable_input(bool p_disable) { + if (p_disable == disable_input) { + return; + } + if (p_disable && GLOBAL_GET("gui/common/drop_mouse_on_gui_input_disabled")) { + _drop_mouse_focus(); + _drop_mouse_over(); + _gui_cancel_tooltip(); + } disable_input = p_disable; } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index c748c5c30bd8..488e0e89646b 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -413,6 +413,7 @@ class Viewport : public Node { void _canvas_layer_remove(CanvasLayer *p_canvas_layer); void _drop_mouse_focus(); + void _drop_mouse_over(); void _drop_physics_mouseover(bool p_paused_only = false); void _update_canvas_items(Node *p_node);