Merge pull request #118886 from mihe/scaled-popup-flip-flop

Fix `PopupMenu` input handling when scaled/padded
This commit is contained in:
Thaddeus Crews
2026-05-14 09:06:47 -05:00
3 changed files with 12 additions and 24 deletions
+10 -15
View File
@@ -1195,7 +1195,7 @@ void PopupMenu::_close_or_suspend() {
if (this_submenu_index != -1) { // Is a submenu.
PopupMenu *parent_popup = Object::cast_to<PopupMenu>(get_parent());
ERR_FAIL_NULL(parent_popup);
Point2 mouse_pos = is_embedded() ? parent_popup->get_mouse_position() : Point2(DisplayServer::get_singleton()->mouse_get_position() - parent_popup->get_position());
Point2 mouse_pos = is_embedded() ? parent_popup->get_mouse_position() * parent_popup->get_content_scale_factor() : Point2(DisplayServer::get_singleton()->mouse_get_position() - parent_popup->get_position());
if (parent_popup->_get_mouse_over(mouse_pos) == this_submenu_index) {
parent_popup->submenu_mouse_exited_ticks_msec = -1;
parent_popup->mouse_movement_was_tested = false;
@@ -2446,7 +2446,7 @@ void PopupMenu::_submenu_hidden() {
queue_accessibility_update();
control->queue_redraw();
if (!activated_by_keyboard) {
Point2 mouse_pos = is_embedded() ? get_mouse_position() : Point2(DisplayServer::get_singleton()->mouse_get_position() - get_position());
Point2 mouse_pos = is_embedded() ? get_mouse_position() * get_content_scale_factor() : Point2(DisplayServer::get_singleton()->mouse_get_position() - get_position());
_mouse_over_update(mouse_pos);
}
}
@@ -3271,19 +3271,6 @@ bool PopupMenu::get_allow_search() const {
return allow_search;
}
String PopupMenu::get_tooltip(const Point2 &p_pos) const {
Point2 pos = p_pos;
// Adjust for the top style margin and search bar.
pos.y += scroll_container->get_global_position().y;
int over = _get_mouse_over(pos);
if (over < 0 || over >= items.size()) {
return "";
}
return items[over].tooltip;
}
void PopupMenu::set_search_bar_enabled(bool p_enabled) {
search_bar_enabled = p_enabled;
_update_search_bar_visibility();
@@ -3837,3 +3824,11 @@ PopupMenu::PopupMenu() {
PopupMenu::~PopupMenu() {
unbind_global_menu();
}
String PopupMenuItems::get_tooltip(const Point2 &p_pos) const {
int over = popup->_get_mouse_over(get_global_transform_with_canvas().xform(p_pos) * popup->get_content_scale_factor());
if (over < 0 || over >= popup->items.size()) {
return "";
}
return popup->items[over].tooltip;
}
+1 -2
View File
@@ -423,8 +423,6 @@ public:
void clear(bool p_free_submenus = true);
virtual String get_tooltip(const Point2 &p_pos) const;
#ifdef TOOLS_ENABLED
PackedStringArray get_configuration_warnings() const override;
#endif
@@ -469,4 +467,5 @@ public:
virtual RID get_focused_accessibility_element() const override;
virtual void gui_input(const Ref<InputEvent> &p_event) override;
virtual String get_tooltip(const Point2 &p_pos) const override;
};
+1 -7
View File
@@ -44,7 +44,6 @@ STATIC_ASSERT_INCOMPLETE_TYPE(class, RenderingServer);
#include "scene/gui/control.h"
#include "scene/gui/label.h"
#include "scene/gui/popup.h"
#include "scene/gui/popup_menu.h"
#include "scene/gui/subviewport_container.h"
#include "scene/main/canvas_layer.h"
#include "scene/main/scene_tree.h"
@@ -1567,14 +1566,9 @@ void Viewport::_gui_cancel_tooltip() {
String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_tooltip_owner) {
Vector2 pos = p_pos;
String tooltip;
PopupMenu *menu = Object::cast_to<PopupMenu>(this);
while (p_control) {
if (menu) {
tooltip = menu->get_tooltip(pos);
} else {
tooltip = p_control->get_tooltip(pos);
}
tooltip = p_control->get_tooltip(pos);
if (r_tooltip_owner) {
*r_tooltip_owner = p_control;