diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml
index c736a6aa3768..2e72fd7a57c9 100644
--- a/doc/classes/Button.xml
+++ b/doc/classes/Button.xml
@@ -113,6 +113,9 @@
[StyleBox] used when the [Button] is being hovered.
+
+ [StyleBox] used when the [Button] is being hovered and pressed.
+
Default [StyleBox] for the [Button].
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index b34ce80dde0a..0a0b0dab58ea 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -83,7 +83,12 @@ void GDScript::_clear_pending_func_states() {
// Order matters since clearing the stack may already cause
// the GDSCriptFunctionState to be destroyed and thus removed from the list.
pending_func_states.remove(E);
- E->self()->_clear_stack();
+ GDScriptFunctionState *state = E->self();
+ ObjectID state_id = state->get_instance_id();
+ state->_clear_connections();
+ if (ObjectDB::get_instance(state_id)) {
+ state->_clear_stack();
+ }
}
GDScriptLanguage::get_singleton()->lock.unlock();
}
@@ -1372,7 +1377,12 @@ GDScriptInstance::~GDScriptInstance() {
// Order matters since clearing the stack may already cause
// the GDSCriptFunctionState to be destroyed and thus removed from the list.
pending_func_states.remove(E);
- E->self()->_clear_stack();
+ GDScriptFunctionState *state = E->self();
+ ObjectID state_id = state->get_instance_id();
+ state->_clear_connections();
+ if (ObjectDB::get_instance(state_id)) {
+ state->_clear_stack();
+ }
}
if (script.is_valid() && owner) {
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index d58164ffa971..233e3b378edc 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -1855,6 +1855,15 @@ void GDScriptFunctionState::_clear_stack() {
}
}
+void GDScriptFunctionState::_clear_connections() {
+ List conns;
+ get_signals_connected_to_this(&conns);
+ for (List::Element *E = conns.front(); E; E = E->next()) {
+ Object::Connection &c = E->get();
+ c.source->disconnect(c.signal, c.target, c.method);
+ }
+}
+
void GDScriptFunctionState::_bind_methods() {
ClassDB::bind_method(D_METHOD("resume", "arg"), &GDScriptFunctionState::resume, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("is_valid", "extended_check"), &GDScriptFunctionState::is_valid, DEFVAL(false));
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index a77094c31fd2..929f787ef225 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -375,6 +375,7 @@ class GDScriptFunctionState : public Reference {
Variant resume(const Variant &p_arg = Variant());
void _clear_stack();
+ void _clear_connections();
GDScriptFunctionState();
~GDScriptFunctionState();
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 750c41c5b58e..e6528c037d14 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -32,8 +32,6 @@
#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
-#include "core/print_string.h"
-#include "core/translation.h"
String PopupMenu::_get_accel_text(int p_item) const {
ERR_FAIL_INDEX_V(p_item, items.size(), String());
@@ -119,8 +117,7 @@ int PopupMenu::_get_items_total_height() const {
items_total_height += MAX(items[i].get_icon_size().height, font_height) + vsep;
}
- // Subtract a separator which is not needed for the last item.
- return items_total_height - vsep;
+ return items_total_height;
}
void PopupMenu::_scroll_to_item(int p_item) {
@@ -149,16 +146,12 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
int vseparation = get_constant("vseparation");
float font_h = get_font("font")->get_height();
- Point2 ofs = style->get_offset() + Point2(0, vseparation / 2);
+ real_t ofs = style->get_margin(MARGIN_TOP) + control->get_position().y;
for (int i = 0; i < items.size(); i++) {
- if (i > 0) {
- ofs.y += vseparation;
- }
+ ofs += MAX(items[i].get_icon_size().height, font_h) + vseparation;
- ofs.y += MAX(items[i].get_icon_size().height, font_h);
-
- if (p_over.y - control->get_position().y < ofs.y) {
+ if (p_over.y < ofs) {
return i;
}
}
@@ -328,7 +321,7 @@ void PopupMenu::_gui_input(const Ref &p_event) {
// Make an area which does not include v scrollbar, so that items are not activated when dragging scrollbar.
Transform2D xform = get_global_transform_with_canvas();
- Point2 item_origin = xform.get_origin();
+ Point2 item_origin = scroll_container->get_global_position();
float scroll_width = scroll_container->get_v_scrollbar()->is_visible_in_tree() ? scroll_container->get_v_scrollbar()->get_size().width : 0;
Size2 item_size = (control->get_global_rect().get_size() - Vector2(scroll_width, 0)) * xform.get_scale();
Rect2 item_clickable_area = Rect2(item_origin, item_size);
@@ -465,7 +458,6 @@ void PopupMenu::_draw_items() {
margin_size.width = margin_container->get_constant("margin_right") + margin_container->get_constant("margin_left");
margin_size.height = margin_container->get_constant("margin_top") + margin_container->get_constant("margin_bottom");
- Ref style = get_stylebox("panel");
Ref hover = get_stylebox("hover");
Ref font = get_font("font");
select_font(font);
@@ -508,7 +500,7 @@ void PopupMenu::_draw_items() {
check_ofs = MAX(get_icon("checked")->get_width(), get_icon("radio_checked")->get_width()) + hseparation;
}
- Point2 ofs = Point2();
+ Point2 ofs = Point2(0, vseparation / 2);
// Loop through all items and draw each.
for (int i = 0; i < items.size(); i++) {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 10c5e26b5f6e..ffcbd7906ede 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1722,7 +1722,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
cache.click_id = c.buttons[j].id;
cache.click_item = p_item;
cache.click_column = col;
- cache.click_pos = get_global_mouse_position() - get_global_position();
+ cache.click_pos = get_local_mouse_position();
update();
//emit_signal("button_pressed");
return -1;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 375d711e4d5d..bb94d2e22c5c 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -230,6 +230,7 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const
theme->set_stylebox("normal", "Button", sb_button_normal);
theme->set_stylebox("pressed", "Button", sb_button_pressed);
theme->set_stylebox("hover", "Button", sb_button_hover);
+ theme->set_stylebox("hover_pressed", "Button", sb_button_hover);
theme->set_stylebox("disabled", "Button", sb_button_disabled);
theme->set_stylebox("focus", "Button", sb_button_focus);