diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index b6a407e0421..4d0f453fe09 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -128,6 +128,13 @@
Returns the [Control] having the focus within this viewport. If no [Control] has the focus, returns null.
+
+
+
+ Returns the [Control] that the mouse is currently hovering over in this viewport. If no [Control] has the cursor, returns null.
+ Typically the leaf [Control] node or deepest level of the subtree which claims hover. This is very useful when used together with [method Node.is_ancestor_of] to find if the mouse is within a control tree.
+
+
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 8cb7614dfd8..89ec5636ab7 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -3518,6 +3518,11 @@ Control *Viewport::gui_get_focus_owner() const {
return gui.key_focus;
}
+Control *Viewport::gui_get_hovered_control() const {
+ ERR_READ_THREAD_GUARD_V(nullptr);
+ return gui.mouse_over;
+}
+
void Viewport::set_msaa_2d(MSAA p_msaa) {
ERR_MAIN_THREAD_GUARD;
ERR_FAIL_INDEX(p_msaa, MSAA_MAX);
@@ -4557,6 +4562,7 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("gui_release_focus"), &Viewport::gui_release_focus);
ClassDB::bind_method(D_METHOD("gui_get_focus_owner"), &Viewport::gui_get_focus_owner);
+ ClassDB::bind_method(D_METHOD("gui_get_hovered_control"), &Viewport::gui_get_hovered_control);
ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input);
ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 6efa98ece85..43a89c8a0b1 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -610,6 +610,7 @@ public:
void gui_release_focus();
Control *gui_get_focus_owner() const;
+ Control *gui_get_hovered_control() const;
PackedStringArray get_configuration_warnings() const override;