[Bf-blender-cvs] [a4ed0f51c15] blender-v3.2-release: Fix click detection for simulated events

Campbell Barton noreply at git.blender.org
Tue May 17 09:49:53 CEST 2022


Commit: a4ed0f51c1560436a4e4f9b9dcd7cb048b4b2397
Author: Campbell Barton
Date:   Tue May 17 17:19:30 2022 +1000
Branches: blender-v3.2-release
https://developer.blender.org/rBa4ed0f51c1560436a4e4f9b9dcd7cb048b4b2397

Fix click detection for simulated events

Refactoring event click-drag detection broke click detection for
simulated events. Resolve this by sharing logic for update previous
values in `wmWindow.eventstate` for regular event handling
(no functional changes for non-simulated events). Failure to detect
clicks for simulated events broke the undo test
`test_undo.view3d_multi_mode_select` in `../lib/tests/ui_simulate/run.py`.
All undo tests now pass.

===================================================================

M	source/blender/windowmanager/intern/wm_event_system.c

===================================================================

diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 1c3f7ed3e7a..4b8552a4ec3 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -102,6 +102,11 @@ static int wm_operator_call_internal(bContext *C,
 static bool wm_operator_check_locked_interface(bContext *C, wmOperatorType *ot);
 static wmEvent *wm_event_add_mousemove_to_head(wmWindow *win);
 
+static void wm_event_state_update_and_click_set_ex(wmEvent *event,
+                                                   wmEvent *event_state,
+                                                   const bool is_keyboard,
+                                                   const bool check_double_click);
+
 /* -------------------------------------------------------------------- */
 /** \name Event Management
  * \{ */
@@ -147,17 +152,7 @@ wmEvent *WM_event_add_simulate(wmWindow *win, const wmEvent *event_to_add)
     copy_v2_v2_int(event->prev_xy, win->eventstate->xy);
   }
   else if (ISKEYBOARD_OR_BUTTON(event->type)) {
-    win->eventstate->prev_val = event->prev_val = win->eventstate->val;
-    win->eventstate->prev_type = event->prev_type = win->eventstate->type;
-
-    win->eventstate->val = event->val;
-    win->eventstate->type = event->type;
-
-    if (event->val == KM_PRESS) {
-      if ((event->flag & WM_EVENT_IS_REPEAT) == 0) {
-        copy_v2_v2_int(win->eventstate->prev_press_xy, event->xy);
-      }
-    }
+    wm_event_state_update_and_click_set_ex(event, win->eventstate, ISKEYBOARD(event->type), false);
   }
   return event;
 }
@@ -4950,10 +4945,14 @@ static wmEvent *wm_event_add_trackpad(wmWindow *win, const wmEvent *event, int d
 
 /**
  * Update the event-state for any kind of event that supports #KM_PRESS / #KM_RELEASE.
+ *
+ * \param check_double_click: Optionally skip checking for double-click events.
+ * Needed for event simulation where the time of click events is not so predictable.
  */
-static void wm_event_state_update_and_click_set(const GHOST_TEventType type,
-                                                wmEvent *event,
-                                                wmEvent *event_state)
+static void wm_event_state_update_and_click_set_ex(wmEvent *event,
+                                                   wmEvent *event_state,
+                                                   const bool is_keyboard,
+                                                   const bool check_double_click)
 {
   BLI_assert(ISKEYBOARD_OR_BUTTON(event->type));
   BLI_assert(ELEM(event->val, KM_PRESS, KM_RELEASE));
@@ -4969,7 +4968,7 @@ static void wm_event_state_update_and_click_set(const GHOST_TEventType type,
   /* It's important only to write into the `event_state` modifier for keyboard
    * events because emulate MMB clears one of the modifiers in `event->modifier`,
    * making the second press not behave as if the modifier is pressed, see T96279. */
-  if (ELEM(type, GHOST_kEventKeyDown, GHOST_kEventKeyUp)) {
+  if (is_keyboard) {
     event_state->modifier = event->modifier;
   }
   event_state->flag = (event->flag & event_state_flag_mask);
@@ -4977,7 +4976,7 @@ static void wm_event_state_update_and_click_set(const GHOST_TEventType type,
    * since the `event_state` and the `event` are not kept in sync. */
 
   /* Double click test. */
-  if (wm_event_is_double_click(event)) {
+  if (check_double_click && wm_event_is_double_click(event)) {
     CLOG_INFO(WM_LOG_HANDLERS, 1, "DBL_CLICK: detected");
     event->val = KM_DBL_CLICK;
   }
@@ -4988,6 +4987,15 @@ static void wm_event_state_update_and_click_set(const GHOST_TEventType type,
   }
 }
 
+static void wm_event_state_update_and_click_set(wmEvent *event,
+                                                wmEvent *event_state,
+                                                const GHOST_TEventType type)
+{
+  const bool is_keyboard = ELEM(type, GHOST_kEventKeyDown, GHOST_kEventKeyUp);
+  const bool check_double_click = true;
+  wm_event_state_update_and_click_set_ex(event, event_state, is_keyboard, check_double_click);
+}
+
 void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void *customdata)
 {
   if (UNLIKELY(G.f & G_FLAG_EVENT_SIMULATE)) {
@@ -5147,7 +5155,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
       wm_tablet_data_from_ghost(&bd->tablet, &event.tablet);
 
       wm_eventemulation(&event, false);
-      wm_event_state_update_and_click_set(type, &event, event_state);
+      wm_event_state_update_and_click_set(&event, event_state, type);
 
       /* Add to other window if event is there (not to both!). */
       wmWindow *win_other = wm_event_cursor_other_windows(wm, win, &event);
@@ -5271,7 +5279,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
       }
 
       /* It's important `event.modifier` has been initialized first. */
-      wm_event_state_update_and_click_set(type, &event, event_state);
+      wm_event_state_update_and_click_set(&event, event_state, type);
 
       /* If test_break set, it catches this. Do not set with modifier presses.
        * Exclude modifiers because MS-Windows uses these to bring up the task manager.
@@ -5345,7 +5353,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
       event.custom = 0;
       event.customdata = NULL;
 
-      wm_event_state_update_and_click_set(type, &event, event_state);
+      wm_event_state_update_and_click_set(&event, event_state, type);
 
       wm_event_add(win, &event);



More information about the Bf-blender-cvs mailing list