From a32d3663c45815984aaf57b2ad59cbf0c906f1fe Mon Sep 17 00:00:00 2001 From: Michael Alexsander Date: Sun, 9 Feb 2025 14:50:47 -0300 Subject: [PATCH] Fix popup shadows misbehaving with `content_scale_factor` --- scene/gui/popup.cpp | 10 ++++++++-- scene/gui/popup_menu.cpp | 30 ++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 94d7303ae50..cbba65e0088 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -247,8 +247,14 @@ void PopupPanel::_input_from_window(const Ref &p_event) { Ref b = p_event; // Hide it if the shadows have been clicked. - if (b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::LEFT && !panel->get_global_rect().has_point(b->get_position())) { - _close_pressed(); + if (b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::LEFT) { + Rect2 panel_area = panel->get_global_rect(); + float win_scale = get_content_scale_factor(); + panel_area.position *= win_scale; + panel_area.size *= win_scale; + if (!panel_area.has_point(b->get_position())) { + _close_pressed(); + } } } else { WARN_PRINT_ONCE("PopupPanel has received an invalid InputEvent. Consider filtering out invalid events."); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 092a12bd148..b6dc7575469 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -327,16 +327,17 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const { item_clickable_area.size.width -= scroll_width; } float win_scale = get_content_scale_factor(); - item_clickable_area.position.y = (item_clickable_area.position.y + theme_cache.panel_style->get_margin(SIDE_TOP)) * win_scale; + item_clickable_area.position.x += theme_cache.panel_style->get_margin(SIDE_LEFT); + item_clickable_area.position.y += theme_cache.panel_style->get_margin(SIDE_TOP); + item_clickable_area.position *= win_scale; item_clickable_area.size.y -= theme_cache.panel_style->get_margin(SIDE_TOP) + theme_cache.panel_style->get_margin(SIDE_BOTTOM); item_clickable_area.size *= win_scale; - if (p_over.x < item_clickable_area.position.x || p_over.x >= item_clickable_area.position.x + item_clickable_area.size.width || - p_over.y < item_clickable_area.position.y || p_over.y >= item_clickable_area.position.y + item_clickable_area.size.height) { + if (!item_clickable_area.has_point(p_over)) { return -1; } - float ofs = item_clickable_area.position.y + theme_cache.v_separation * 0.5; + float ofs = item_clickable_area.position.y + (float)theme_cache.v_separation * win_scale * 0.5; for (int i = 0; i < items.size(); i++) { ofs += i > 0 ? (float)theme_cache.v_separation * win_scale : (float)theme_cache.v_separation * win_scale * 0.5; ofs += _get_item_height(i) * win_scale; @@ -430,7 +431,7 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) { this_rect.size.x, scaled_ofs_cache + scroll_offset + theme_cache.panel_style->get_margin(SIDE_TOP) * win_scale - theme_cache.v_separation / 2)); // If there is an area below the submenu item, add an autohide area there. - if (scaled_ofs_cache + scaled_height_cache + scroll_offset <= control->get_size().height) { + if (scaled_ofs_cache + scaled_height_cache + scroll_offset <= control->get_size().height * win_scale) { const int from = scaled_ofs_cache + scaled_height_cache + scroll_offset + theme_cache.v_separation / 2; submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y + from, this_rect.size.x, this_rect.size.y - from)); } @@ -605,9 +606,13 @@ void PopupMenu::_input_from_window_internal(const Ref &p_event) { } item_clickable_area.size.width -= scroll_width; } - item_clickable_area.position.y = (item_clickable_area.position.y + theme_cache.panel_style->get_margin(SIDE_TOP)) * get_content_scale_factor(); + + float win_scale = get_content_scale_factor(); + item_clickable_area.position.x += theme_cache.panel_style->get_margin(SIDE_LEFT); + item_clickable_area.position.y += theme_cache.panel_style->get_margin(SIDE_TOP); + item_clickable_area.position *= win_scale; item_clickable_area.size.y -= theme_cache.panel_style->get_margin(SIDE_TOP) + theme_cache.panel_style->get_margin(SIDE_BOTTOM); - item_clickable_area.size *= get_content_scale_factor(); + item_clickable_area.size *= win_scale; Ref b = p_event; @@ -622,9 +627,14 @@ void PopupMenu::_input_from_window_internal(const Ref &p_event) { is_scrolling = is_layout_rtl() ? b->get_position().x < item_clickable_area.position.x : b->get_position().x > item_clickable_area.size.width; // Hide it if the shadows have been clicked. - if (get_flag(FLAG_POPUP) && !panel->get_global_rect().has_point(b->get_position())) { - _close_pressed(); - return; + if (get_flag(FLAG_POPUP)) { + Rect2 panel_area = panel->get_global_rect(); + panel_area.position *= win_scale; + panel_area.size *= win_scale; + if (!panel_area.has_point(b->get_position())) { + _close_pressed(); + return; + } } if (!item_clickable_area.has_point(b->get_position())) {