Repository: godotengine/godot (language: cpp)

Issue:
[GUI] Setting a control's recursive mode to disabled does not work on start
### Tested versions

latest main branch [2303ce843a362cf5497ca3336451de23793eb711]

### System information

Godot v4.5.dev (2303ce843) - Windows 10 (build 19044) - Multi-window, 4 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4060 Ti (NVIDIA; 32.0.15.7260) - AMD Ryzen 9 5900X 12-Core Processor (24 threads)

### Issue description

#97495 introduces properties for managing children's controls' focus mode and mouse filters. However, this won't work if you set the recursive behavior to `Disable` in the editor.

### Steps to reproduce

https://github.com/user-attachments/assets/c498932f-8874-4a14-a693-fe0e09b74443


### Minimal reproduction project (MRP)

[MrpRecursiveGuiDisable.zip](https://github.com/user-attachments/files/19391423/MrpRecursiveGuiDisable.zip)


Discussion / hints:

Fix patch:
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index a64de8fb3c5d..8d34746529e7 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1880,16 +1880,20 @@ void Control::set_mouse_recursive_behavior(RecursiveBehavior p_recursive_mouse_b
 	if (data.mouse_recursive_behavior == p_recursive_mouse_behavior) {
 		return;
 	}
+	_set_mouse_recursive_behavior_ignore_cache(p_recursive_mouse_behavior);
+}
+
+void Control::_set_mouse_recursive_behavior_ignore_cache(RecursiveBehavior p_recursive_mouse_behavior) {
 	data.mouse_recursive_behavior = p_recursive_mouse_behavior;
 	if (p_recursive_mouse_behavior == RECURSIVE_BEHAVIOR_INHERITED) {
 		Control *parent = get_parent_control();
 		if (parent) {
-			_apply_mouse_behavior_recursively(parent->data.parent_mouse_recursive_behavior, false);
+			_propagate_mouse_behavior_recursively(parent->data.parent_mouse_recursive_behavior, false);
 		} else {
-			_apply_mouse_behavior_recursively(RECURSIVE_BEHAVIOR_ENABLED, false);
+			_propagate_mouse_behavior_recursively(RECURSIVE_BEHAVIOR_ENABLED, false);
 		}
 	} else {
-		_apply_mouse_behavior_recursively(p_recursive_mouse_behavior, false);
+		_propagate_mouse_behavior_recursively(p_recursive_mouse_behavior, false);
 	}
 
 	if (get_viewport()) {
@@ -2064,16 +2068,20 @@ void Control::set_focus_recursive_behavior(RecursiveBehavior p_recursive_focus_b
 	if (data.focus_recursive_behavior == p_recursive_focus_behavior) {
 		return;
 	}
+	_set_focus_recursive_behavior_ignore_cache(p_recursive_focus_behavior);
+}
+
+void Control::_set_focus_recursive_behavior_ignore_cache(RecursiveBehavior p_recursive_focus_behavior) {
 	data.focus_recursive_behavior = p_recursive_focus_behavior;
 	if (p_recursive_focus_behavior == RECURSIVE_BEHAVIOR_INHERITED) {
 		Control *parent = get_parent_control();
 		if (parent) {
-			_apply_focus_behavior_recursively(parent->data.parent_focus_recursive_behavior, false);
+			_propagate_focus_behavior_recursively(parent->data.parent_focus_recursive_behavior, false);
 		} else {
-			_apply_focus_behavior_recursively(RECURSIVE_BEHAVIOR_ENABLED, false);
+			_propagate_focus_behavior_recursively(RECURSIVE_BEHAVIOR_ENABLED, false);
 		}
 	} else {
-		_apply_focus_behavior_recursively(p_recursive_focus_behavior, false);
+		_propagate_focus_behavior_recursively(p_recursive_focus_behavior, false);
 	}
 }
 
@@ -2449,7 +2457,7 @@ bool Control::_is_focus_disabled_recursively() const {
 	return false;
 }
 
-void Control::_apply_focus_behavior_recursively(RecursiveBehavior p_focus_recursive_behavior, bool p_skip_non_inherited) {
+void Control::_propagate_focus_behavior_recursively(RecursiveBehavior p_focus_recursive_behavior, bool p_skip_non_inherited) {
 	if (is_inside_tree() && (data.focus_recursive_behavior == RECURSIVE_BEHAVIOR_DISABLED || (data.focus_recursive_behavior == RECURSIVE_BEHAVIOR_INHERITED && p_focus_recursive_behavior == RECURSIVE_BEHAVIOR_DISABLED)) && has_focus()) {
 		release_focus();
 	}
@@ -2463,7 +2471,7 @@ void Control::_apply_focus_behavior_recursively(RecursiveBehavior p_focus_recurs
 	for (int i = 0; i < get_child_count(); i++) {
 		Control *control = Object::cast_to<Control>(get_child(i));
 		if (control) {
-			control->_apply_focus_behavior_recursively(p_focus_recursive_behavior, true);
+			control->_propagate_focus_behavior_recursively(p_focus_recursive_behavior, true);
 		}
 	}
 }
@@ -2480,7 +2488,7 @@ bool Control::_is_parent_mouse_disabled() const {
 	return false;
 }
 
-void Control::_apply_mouse_behavior_recursively(RecursiveBehavior p_mouse_recursive_behavior, bool p_skip_non_inherited) {
+void Control::_propagate_mouse_behavior_recursively(RecursiveBehavior p_mouse_recursive_behavior, bool p_skip_non_inherited) {
 	if (p_skip_non_inherited && data.mouse_recursive_behavior != RECURSIVE_BEHAVIOR_INHERITED) {
 		return;
 	}
@@ -2490,7 +2498,7 @@ void Control::_apply_mouse_behavior_recursively(RecursiveBehavior p_mouse_recurs
 	for (int i = 0; i < get_child_count(); i++) {
 		Control *control = Object::cast_to<Control>(get_child(i));
 		if (control) {
-			control->_apply_mouse_behavior_recursively(p_mouse_recursive_behavior, true);
+			control->_propagate_mouse_behavior_recursively(p_mouse_recursive_behavior, true);
 		}
 	}
 }
@@ -3450,8 +3458,8 @@ void Control::_notification(int p_notification) {
 
 			_update_layout_mode();
 
-			set_focus_recursive_behavior(data.focus_recursive_behavior);
-			set_mouse_recursive_behavior(data.mouse_recursive_behavior);
+			_set_focus_recursive_behavior_ignore_cache(data.focus_recursive_behavior);
+			_set_mouse_recursive_behavior_ignore_cache(data.mouse_recursive_behavior);
 		} break;
 
 		case NOTIFICATION_UNPARENTED: {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 8188b3ba31d0..b2001fdd259f 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -330,8 +330,10 @@ class Control : public CanvasItem {
 	void _window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Rect2 &p_rect, const Rect2 &p_clamp, real_t p_min, real_t &r_closest_dist_squared, Control **r_closest);
 	Control *_get_focus_neighbor(Side p_side, int p_count = 0);
 	bool _is_focus_disabled_recursively() const;
-	void _apply_focus_behavior_recursively(RecursiveBehavior p_focus_recursive_behavior, bool p_force);
-	void _apply_mouse_behavior_recursively(RecursiveBehavior p_focus_recursive_behavior, bool p_force);
+	void _propagate_focus_behavior_recursively(RecursiveBehavior p_focus_recursive_behavior, bool p_force);
+	void _propagate_mouse_behavior_recursively(RecursiveBehavior p_focus_recursive_behavior, bool p_force);
+	void _set_mouse_recursive_behavior_ignore_cache(RecursiveBehavior p_recursive_mouse_behavior);
+	void _set_focus_recursive_behavior_ignore_cache(RecursiveBehavior p_recursive_mouse_behavior);
 
 	// Theming.
 


Test patch: