Browse Source

Revert "Fix selecting popup menu items on mouse release"

Rémi Verschelde 1 year ago
parent
commit
8f1915eb90
2 changed files with 45 additions and 50 deletions
  1. 43 48
      scene/gui/popup_menu.cpp
  2. 2 2
      scene/gui/popup_menu.h

+ 43 - 48
scene/gui/popup_menu.cpp

@@ -456,9 +456,6 @@ void PopupMenu::_input_from_window(const Ref<InputEvent> &p_event) {
 }
 
 void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) {
-	Ref<InputEventMouseButton> b = p_event;
-	Ref<InputEventMouseMotion> m = p_event;
-
 	if (!items.is_empty()) {
 		Input *input = Input::get_singleton();
 		Ref<InputEventJoypadMotion> joypadmotion_event = p_event;
@@ -587,58 +584,53 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) {
 		}
 	}
 
-	if (m.is_valid() && drag_to_press) {
-		BitField<MouseButtonMask> initial_button_mask = m->get_button_mask();
-		if (!initial_button_mask.has_flag(mouse_button_to_mask(MouseButton::LEFT)) && !initial_button_mask.has_flag(mouse_button_to_mask(MouseButton::RIGHT))) {
-			mouse_is_pressed = false;
-		}
-
-		if (!item_clickable_area.has_point(m->get_position()) && !mouse_is_pressed) {
-			drag_to_press = false;
-		}
-	}
+	Ref<InputEventMouseButton> b = p_event;
 
-	if ((b.is_valid() && b->is_pressed()) || (!mouse_is_pressed && drag_to_press)) {
-		if (b.is_valid()) {
-			MouseButton button_idx = b->get_button_index();
-			if (button_idx != MouseButton::LEFT && button_idx != MouseButton::RIGHT) {
-				return;
-			}
-		} else {
-			uint64_t now = OS::get_singleton()->get_ticks_msec();
-			uint64_t diff = now - popup_time_msec;
-			if (diff < 250) {
-				drag_to_press = false;
-				return;
-			}
+	if (b.is_valid()) {
+		if (!item_clickable_area.has_point(b->get_position())) {
+			return;
 		}
 
-		drag_to_press = false;
-
-		int over = -1;
-
-		if (m.is_valid()) {
-			over = _get_mouse_over(m->get_position());
-		} else if (b.is_valid()) {
-			over = _get_mouse_over(b->get_position());
-		}
+		MouseButton button_idx = b->get_button_index();
+		if (!b->is_pressed()) {
+			// Activate the item on release of either the left mouse button or
+			// any mouse button held down when the popup was opened.
+			// This allows for opening the popup and triggering an action in a single mouse click.
+			if (button_idx == MouseButton::LEFT || initial_button_mask.has_flag(mouse_button_to_mask(button_idx))) {
+				bool was_during_grabbed_click = during_grabbed_click;
+				during_grabbed_click = false;
+				initial_button_mask.clear();
+
+				// Disable clicks under a time threshold to avoid selection right when opening the popup.
+				uint64_t now = OS::get_singleton()->get_ticks_msec();
+				uint64_t diff = now - popup_time_msec;
+				if (diff < 150) {
+					return;
+				}
 
-		if (over < 0) {
-			hide();
-			return;
-		}
+				int over = _get_mouse_over(b->get_position());
+				if (over < 0) {
+					if (!was_during_grabbed_click) {
+						hide();
+					}
+					return;
+				}
 
-		if (items[over].separator || items[over].disabled) {
-			return;
-		}
+				if (items[over].separator || items[over].disabled) {
+					return;
+				}
 
-		if (!items[over].submenu.is_empty()) {
-			_activate_submenu(over);
-			return;
+				if (!items[over].submenu.is_empty()) {
+					_activate_submenu(over);
+					return;
+				}
+				activate_item(over);
+			}
 		}
-		activate_item(over);
 	}
 
+	Ref<InputEventMouseMotion> m = p_event;
+
 	if (m.is_valid()) {
 		if (m->get_velocity().is_zero_approx()) {
 			return;
@@ -1070,6 +1062,11 @@ void PopupMenu::_notification(int p_what) {
 			}
 		} break;
 
+		case NOTIFICATION_POST_POPUP: {
+			initial_button_mask = Input::get_singleton()->get_mouse_button_mask();
+			during_grabbed_click = (bool)initial_button_mask;
+		} break;
+
 		case NOTIFICATION_INTERNAL_PROCESS: {
 			Input *input = Input::get_singleton();
 
@@ -2805,8 +2802,6 @@ void PopupMenu::popup(const Rect2i &p_bounds) {
 	moved = Vector2();
 	popup_time_msec = OS::get_singleton()->get_ticks_msec();
 	Popup::popup(p_bounds);
-	drag_to_press = true;
-	mouse_is_pressed = true;
 }
 
 PopupMenu::PopupMenu() {

+ 2 - 2
scene/gui/popup_menu.h

@@ -107,8 +107,8 @@ class PopupMenu : public Popup {
 	Timer *submenu_timer = nullptr;
 	List<Rect2> autohide_areas;
 	Vector<Item> items;
-	bool mouse_is_pressed = true;
-	bool drag_to_press = true;
+	BitField<MouseButtonMask> initial_button_mask;
+	bool during_grabbed_click = false;
 	int mouse_over = -1;
 	int submenu_over = -1;
 	String _get_accel_text(const Item &p_item) const;