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);