@@ -788,7 +788,7 @@ void Viewport::_process_picking() {
788788 SubViewportContainer *parent_svc = Object::cast_to<SubViewportContainer>(get_parent ());
789789 bool parent_ignore_mouse = (parent_svc && parent_svc->get_mouse_filter_with_override () == Control::MOUSE_FILTER_IGNORE);
790790 bool create_passive_hover_event = true ;
791- if (gui.mouse_over || parent_ignore_mouse) {
791+ if (gui.mouse_over . is_valid () || parent_ignore_mouse) {
792792 // When the mouse is over a Control node, passive hovering would cause input events for Colliders, that are behind Control nodes.
793793 // When parent SubViewportContainer ignores mouse, that setting should be respected.
794794 create_passive_hover_event = false ;
@@ -1950,7 +1950,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
19501950 if (control->_is_focusable ()) {
19511951 // Grabbing unhovered focus can cause issues when mouse is dragged
19521952 // with another button held down.
1953- if (gui.mouse_over_hierarchy .has (control)) {
1953+ if (gui.mouse_over_hierarchy .has (control-> get_instance_id () )) {
19541954 // Hide the focus when it comes from a click.
19551955 control->grab_focus (true );
19561956 }
@@ -2526,7 +2526,8 @@ void Viewport::_gui_hide_control(Control *p_control) {
25262526 if (gui.key_focus == p_control) {
25272527 gui_release_focus ();
25282528 }
2529- if (gui.mouse_over == p_control || gui.mouse_over_hierarchy .has (p_control)) {
2529+ ObjectID over_id = p_control ? p_control->get_instance_id () : ObjectID ();
2530+ if (gui.mouse_over == over_id || gui.mouse_over_hierarchy .has (over_id)) {
25302531 _drop_mouse_over (p_control->get_parent_control ());
25312532 }
25322533 if (gui.drag_mouse_over == p_control) {
@@ -2545,7 +2546,8 @@ void Viewport::_gui_remove_control(Control *p_control) {
25452546 if (gui.key_focus == p_control) {
25462547 gui.key_focus = nullptr ;
25472548 }
2548- if (gui.mouse_over == p_control || gui.mouse_over_hierarchy .has (p_control)) {
2549+ ObjectID over_id = p_control ? p_control->get_instance_id () : ObjectID ();
2550+ if (gui.mouse_over == over_id || gui.mouse_over_hierarchy .has (over_id)) {
25492551 _drop_mouse_over (p_control->get_parent_control ());
25502552 }
25512553 if (gui.drag_mouse_over == p_control) {
@@ -2561,7 +2563,7 @@ void Viewport::canvas_item_top_level_changed() {
25612563}
25622564
25632565void Viewport::_gui_update_mouse_over () {
2564- if (gui.mouse_over == nullptr || gui.mouse_over_hierarchy .is_empty ()) {
2566+ if (gui.mouse_over . is_null () || gui.mouse_over_hierarchy .is_empty ()) {
25652567 return ;
25662568 }
25672569
@@ -2574,17 +2576,19 @@ void Viewport::_gui_update_mouse_over() {
25742576 }
25752577
25762578 // Rebuild the mouse over hierarchy.
2577- LocalVector<Control * > new_mouse_over_hierarchy;
2578- LocalVector<Control * > needs_enter;
2579+ LocalVector<ObjectID > new_mouse_over_hierarchy;
2580+ LocalVector<ObjectID > needs_enter;
25792581 LocalVector<int > needs_exit;
25802582
2581- CanvasItem *ancestor = gui.mouse_over ;
2583+ CanvasItem *over = ObjectDB::get_instance<CanvasItem>(gui.mouse_over );
2584+ CanvasItem *ancestor = over;
25822585 bool removing = false ;
25832586 bool reached_top = false ;
25842587 while (ancestor) {
25852588 Control *ancestor_control = Object::cast_to<Control>(ancestor);
25862589 if (ancestor_control) {
2587- int found = gui.mouse_over_hierarchy .find (ancestor_control);
2590+ ObjectID ancestor_control_id = ancestor_control->get_instance_id ();
2591+ int found = gui.mouse_over_hierarchy .find (ancestor_control_id);
25882592 if (found >= 0 ) {
25892593 // Remove the node if the propagation chain has been broken or it is now MOUSE_FILTER_IGNORE.
25902594 if (removing || ancestor_control->get_mouse_filter_with_override () == Control::MOUSE_FILTER_IGNORE) {
@@ -2599,10 +2603,10 @@ void Viewport::_gui_update_mouse_over() {
25992603 reached_top = true ;
26002604 }
26012605 if (!removing && ancestor_control->get_mouse_filter_with_override () != Control::MOUSE_FILTER_IGNORE) {
2602- new_mouse_over_hierarchy.push_back (ancestor_control );
2606+ new_mouse_over_hierarchy.push_back (ancestor_control_id );
26032607 // Add the node if it was not found and it is now not MOUSE_FILTER_IGNORE.
26042608 if (found < 0 ) {
2605- needs_enter.push_back (ancestor_control );
2609+ needs_enter.push_back (ancestor_control_id );
26062610 }
26072611 }
26082612 if (ancestor_control->get_mouse_filter_with_override () == Control::MOUSE_FILTER_STOP) {
@@ -2632,15 +2636,18 @@ void Viewport::_gui_update_mouse_over() {
26322636 gui.sending_mouse_enter_exit_notifications = true ;
26332637
26342638 // Send Mouse Exit Self notification.
2635- if (gui. mouse_over && !needs_exit.is_empty () && needs_exit[0 ] == (int )gui.mouse_over_hierarchy .size () - 1 ) {
2636- gui. mouse_over ->notification (Control::NOTIFICATION_MOUSE_EXIT_SELF);
2637- gui.mouse_over = nullptr ;
2639+ if (over && !needs_exit.is_empty () && needs_exit[0 ] == (int )gui.mouse_over_hierarchy .size () - 1 ) {
2640+ over ->notification (Control::NOTIFICATION_MOUSE_EXIT_SELF);
2641+ gui.mouse_over = ObjectID () ;
26382642 }
26392643
26402644 // Send Mouse Exit notifications.
26412645 for (int exit_control_index : needs_exit) {
2642- gui.mouse_over_hierarchy [exit_control_index]->notification (Control::NOTIFICATION_MOUSE_EXIT);
2643- gui.mouse_over_hierarchy [exit_control_index]->emit_signal (SceneStringName (mouse_exited));
2646+ Control *ctrl = ObjectDB::get_instance<Control>(gui.mouse_over_hierarchy [exit_control_index]);
2647+ if (ctrl) {
2648+ ctrl->notification (Control::NOTIFICATION_MOUSE_EXIT);
2649+ ctrl->emit_signal (SceneStringName (mouse_exited));
2650+ }
26442651 }
26452652
26462653 // Update the mouse over hierarchy.
@@ -2651,8 +2658,11 @@ void Viewport::_gui_update_mouse_over() {
26512658
26522659 // Send Mouse Enter notifications.
26532660 for (int i = needs_enter.size () - 1 ; i >= 0 ; i--) {
2654- needs_enter[i]->notification (Control::NOTIFICATION_MOUSE_ENTER);
2655- needs_enter[i]->emit_signal (SceneStringName (mouse_entered));
2661+ Control *ctrl = ObjectDB::get_instance<Control>(needs_enter[i]);
2662+ if (ctrl) {
2663+ ctrl->notification (Control::NOTIFICATION_MOUSE_ENTER);
2664+ ctrl->emit_signal (SceneStringName (mouse_entered));
2665+ }
26562666 }
26572667
26582668 gui.sending_mouse_enter_exit_notifications = false ;
@@ -3247,7 +3257,7 @@ void Viewport::_update_mouse_over(Vector2 p_pos) {
32473257 }
32483258
32493259 if (swrect_border.has_point (p_pos)) {
3250- if (gui.mouse_over ) {
3260+ if (gui.mouse_over . is_valid () ) {
32513261 _drop_mouse_over ();
32523262 } else if (!gui.subwindow_over ) {
32533263 _drop_physics_mouseover ();
@@ -3281,12 +3291,13 @@ void Viewport::_update_mouse_over(Vector2 p_pos) {
32813291
32823292 // Look for Controls at mouse position.
32833293 Control *over = gui_find_control (p_pos);
3294+ ObjectID over_id = over ? over->get_instance_id () : ObjectID ();
32843295 get_section_root_viewport ()->gui .target_control = over;
32853296 bool notify_embedded_viewports = false ;
3286- if (over != gui.mouse_over || (!over && !gui.mouse_over_hierarchy .is_empty ())) {
3297+ if (over_id != gui.mouse_over || (!over && !gui.mouse_over_hierarchy .is_empty ())) {
32873298 // Find the common ancestor of `gui.mouse_over` and `over`.
32883299 Control *common_ancestor = nullptr ;
3289- LocalVector<Control * > over_ancestors;
3300+ LocalVector<ObjectID > over_ancestors;
32903301
32913302 if (over) {
32923303 // Get all ancestors that the mouse is currently over and need an enter signal.
@@ -3295,12 +3306,12 @@ void Viewport::_update_mouse_over(Vector2 p_pos) {
32953306 Control *ancestor_control = Object::cast_to<Control>(ancestor);
32963307 if (ancestor_control) {
32973308 if (ancestor_control->get_mouse_filter_with_override () != Control::MOUSE_FILTER_IGNORE) {
3298- int found = gui.mouse_over_hierarchy .find (ancestor_control);
3309+ int found = gui.mouse_over_hierarchy .find (ancestor_control-> get_instance_id () );
32993310 if (found >= 0 ) {
3300- common_ancestor = gui.mouse_over_hierarchy [found];
3311+ common_ancestor = ObjectDB::get_instance<Control>( gui.mouse_over_hierarchy [found]) ;
33013312 break ;
33023313 }
3303- over_ancestors.push_back (ancestor_control);
3314+ over_ancestors.push_back (ancestor_control-> get_instance_id () );
33043315 }
33053316 if (ancestor_control->get_mouse_filter_with_override () == Control::MOUSE_FILTER_STOP) {
33063317 // MOUSE_FILTER_STOP breaks the propagation chain.
@@ -3315,29 +3326,33 @@ void Viewport::_update_mouse_over(Vector2 p_pos) {
33153326 }
33163327 }
33173328
3318- if (gui.mouse_over || !gui.mouse_over_hierarchy .is_empty ()) {
3329+ if (gui.mouse_over . is_valid () || !gui.mouse_over_hierarchy .is_empty ()) {
33193330 // Send Mouse Exit Self and Mouse Exit notifications.
33203331 _drop_mouse_over (common_ancestor);
33213332 } else {
33223333 _drop_physics_mouseover ();
33233334 }
33243335
33253336 if (over) {
3326- gui.mouse_over = over ;
3337+ gui.mouse_over = over_id ;
33273338 gui.mouse_over_hierarchy .reserve (gui.mouse_over_hierarchy .size () + over_ancestors.size ());
33283339
33293340 gui.sending_mouse_enter_exit_notifications = true ;
33303341
33313342 // Send Mouse Enter notifications to parents first.
33323343 for (int i = over_ancestors.size () - 1 ; i >= 0 ; i--) {
3333- gui.mouse_over_hierarchy .push_back (over_ancestors[i]);
3334- over_ancestors[i]->notification (Control::NOTIFICATION_MOUSE_ENTER);
3335- over_ancestors[i]->emit_signal (SceneStringName (mouse_entered));
3344+ Control *ctrl = ObjectDB::get_instance<Control>(over_ancestors[i]);
3345+ if (ctrl) {
3346+ gui.mouse_over_hierarchy .push_back (over_ancestors[i]);
3347+ ctrl->notification (Control::NOTIFICATION_MOUSE_ENTER);
3348+ ctrl->emit_signal (SceneStringName (mouse_entered));
3349+ }
33363350 }
33373351
33383352 // Send Mouse Enter Self notification.
3339- if (gui.mouse_over ) {
3340- gui.mouse_over ->notification (Control::NOTIFICATION_MOUSE_ENTER_SELF);
3353+ CanvasItem *ctrl = ObjectDB::get_instance<CanvasItem>(gui.mouse_over );
3354+ if (ctrl) {
3355+ ctrl->notification (Control::NOTIFICATION_MOUSE_ENTER_SELF);
33413356 }
33423357
33433358 gui.sending_mouse_enter_exit_notifications = false ;
@@ -3384,7 +3399,7 @@ void Viewport::_mouse_leave_viewport() {
33843399 if (gui.subwindow_over ) {
33853400 gui.subwindow_over ->_mouse_leave_viewport ();
33863401 gui.subwindow_over = nullptr ;
3387- } else if (gui.mouse_over ) {
3402+ } else if (gui.mouse_over . is_valid () ) {
33883403 _drop_mouse_over ();
33893404 }
33903405 notification (NOTIFICATION_VP_MOUSE_EXIT);
@@ -3398,7 +3413,7 @@ void Viewport::_drop_mouse_over(Control *p_until_control) {
33983413 }
33993414
34003415 _gui_cancel_tooltip ();
3401- SubViewportContainer *c = Object::cast_to <SubViewportContainer>(gui.mouse_over );
3416+ SubViewportContainer *c = ObjectDB::get_instance <SubViewportContainer>(gui.mouse_over );
34023417 if (c) {
34033418 for (int i = 0 ; i < c->get_child_count (); i++) {
34043419 SubViewport *v = Object::cast_to<SubViewport>(c->get_child (i));
@@ -3410,21 +3425,23 @@ void Viewport::_drop_mouse_over(Control *p_until_control) {
34103425 }
34113426
34123427 gui.sending_mouse_enter_exit_notifications = true ;
3413- if (gui.mouse_over && gui.mouse_over ->is_inside_tree ()) {
3414- gui.mouse_over ->notification (Control::NOTIFICATION_MOUSE_EXIT_SELF);
3428+ CanvasItem *over = ObjectDB::get_instance<CanvasItem>(gui.mouse_over );
3429+ if (over && over->is_inside_tree ()) {
3430+ over->notification (Control::NOTIFICATION_MOUSE_EXIT_SELF);
34153431 }
34163432 Viewport *section_root = get_section_root_viewport ();
3417- if (section_root && section_root->gui .target_control == gui. mouse_over ) {
3433+ if (section_root && section_root->gui .target_control == over ) {
34183434 section_root->gui .target_control = nullptr ;
34193435 }
3420- gui.mouse_over = nullptr ;
3436+ gui.mouse_over = ObjectID () ;
34213437
34223438 // Send Mouse Exit notifications to children first. Don't send to p_until_control or above.
3423- int notification_until = p_until_control ? gui.mouse_over_hierarchy .find (p_until_control) + 1 : 0 ;
3439+ int notification_until = p_until_control ? gui.mouse_over_hierarchy .find (p_until_control-> get_instance_id () ) + 1 : 0 ;
34243440 for (int i = gui.mouse_over_hierarchy .size () - 1 ; i >= notification_until; i--) {
3425- if (gui.mouse_over_hierarchy [i]->is_inside_tree ()) {
3426- gui.mouse_over_hierarchy [i]->notification (Control::NOTIFICATION_MOUSE_EXIT);
3427- gui.mouse_over_hierarchy [i]->emit_signal (SceneStringName (mouse_exited));
3441+ Control *ctrl = ObjectDB::get_instance<Control>(gui.mouse_over_hierarchy [i]);
3442+ if (ctrl && ctrl->is_inside_tree ()) {
3443+ ctrl->notification (Control::NOTIFICATION_MOUSE_EXIT);
3444+ ctrl->emit_signal (SceneStringName (mouse_exited));
34283445 }
34293446 }
34303447 gui.mouse_over_hierarchy .resize (notification_until);
@@ -3712,7 +3729,7 @@ Control *Viewport::gui_get_focus_owner() const {
37123729
37133730Control *Viewport::gui_get_hovered_control () const {
37143731 ERR_READ_THREAD_GUARD_V (nullptr );
3715- return gui.mouse_over ;
3732+ return ObjectDB::get_instance<Control>( gui.mouse_over ) ;
37163733}
37173734
37183735void Viewport::set_msaa_2d (MSAA p_msaa) {
0 commit comments