diff options
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 104 | ||||
-rw-r--r-- | source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_query.c | 14 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 38 |
4 files changed, 93 insertions, 65 deletions
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 3d8577933cf..8934f714c21 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -238,6 +238,7 @@ enum { KM_SHIFT = (1 << 0), KM_CTRL = (1 << 1), KM_ALT = (1 << 2), + /** Use for Windows-Key on MS-Windows, Command-key on macOS and Super on Linux. */ KM_OSKEY = (1 << 3), /* Used for key-map item creation function arguments. */ @@ -268,7 +269,7 @@ enum { KM_CLICK = 3, KM_DBL_CLICK = 4, /** - * \note The cursor location at the point dragging starts is set to #wmEvent.prev_click_xy + * \note The cursor location at the point dragging starts is set to #wmEvent.prev_press_xy * some operators such as box selection should use this location instead of #wmEvent.xy. */ KM_CLICK_DRAG = 5, @@ -629,23 +630,39 @@ typedef struct wmTabletData { * event comes from event manager and from keymap. * * - * Previous State - * ============== + * Previous State (`prev_*`) + * ========================= * - * Events hold information about the previous event, - * this is used for detecting click and double-click events (the timer is needed for double-click). - * See #wm_event_add_ghostevent for implementation details. + * Events hold information about the previous event. * - * Notes: - * - * - The previous values are only set for mouse button and keyboard events. - * See: #ISKEYBOARD_OR_BUTTON macro. + * - Previous values are only set for events types that generate #KM_PRESS. + * See: #ISKEYBOARD_OR_BUTTON. * * - Previous x/y are exceptions: #wmEvent.prev * these are set on mouse motion, see #MOUSEMOVE & track-pad events. * * - Modal key-map handling sets `prev_val` & `prev_type` to `val` & `type`, * this allows modal keys-maps to check the original values (needed in some cases). + * + * + * Press State (`prev_press_*`) + * ============================ + * + * Events hold information about the state when the last #KM_PRESS event was added. + * This is used for generating #KM_CLICK, #KM_DBL_CLICK & #KM_CLICK_DRAG events. + * See #wm_handlers_do for the implementation. + * + * - Previous values are only set when a #KM_PRESS event is detected. + * See: #ISKEYBOARD_OR_BUTTON. + * + * - The reason to differentiate between "press" and the previous event state is + * the previous event may be set by key-release events. In the case of a single key click + * this isn't a problem however releasing other keys such as modifiers prevents click/click-drag + * events from being detected, see: T89989. + * + * - Mouse-wheel events are excluded even though they generate #KM_PRESS + * as clicking and dragging don't make sense for mouse wheel events. + * */ typedef struct wmEvent { struct wmEvent *next, *prev; @@ -667,38 +684,16 @@ typedef struct wmEvent { /** From ghost, fallback if utf8 isn't set. */ char ascii; - /** The previous value of `type`. */ - short prev_type; - /** The previous value of `val`. */ - short prev_val; - /** - * The previous value of #wmEvent.xy, - * Unlike other previous state variables, this is set on any mouse motion. - * Use `prev_click` for the value at time of pressing. - */ - int prev_xy[2]; - - /** The `type` at the point of the click action. */ - short prev_click_type; - /** The time when the key is pressed, see #PIL_check_seconds_timer. */ - double prev_click_time; - /** The location when the key is pressed (used to enforce drag thresholds). */ - int prev_click_xy[2]; - /** The `modifier` at the point of the click action. */ - uint8_t prev_click_modifier; - /** The `keymodifier` at the point of the click action. */ - short prev_click_keymodifier; - - /** - * Modifier states. - * #KM_SHIFT, #KM_CTRL, #KM_ALT & #KM_OSKEY is apple or windows-key. - */ + /** Modifier states: #KM_SHIFT, #KM_CTRL, #KM_ALT & #KM_OSKEY. */ uint8_t modifier; /** The direction (for #KM_CLICK_DRAG events only). */ int8_t direction; - /** Raw-key modifier (allow using any key as a modifier). */ + /** + * Raw-key modifier (allow using any key as a modifier). + * Compatible with values in `type`. + */ short keymodifier; /** Tablet info, available for mouse move and button events. */ @@ -707,11 +702,44 @@ typedef struct wmEvent { eWM_EventFlag flag; /* Custom data. */ - /** Custom data type, stylus, 6dof, see wm_event_types.h */ + + /** Custom data type, stylus, 6-DOF, see `wm_event_types.h`. */ short custom; short customdata_free; /** Ascii, unicode, mouse-coords, angles, vectors, NDOF data, drag-drop info. */ void *customdata; + + /* Previous State. */ + + /** The previous value of `type`. */ + short prev_type; + /** The previous value of `val`. */ + short prev_val; + /** + * The previous value of #wmEvent.xy, + * Unlike other previous state variables, this is set on any mouse motion. + * Use `prev_press_*` for the value at time of pressing. + */ + int prev_xy[2]; + + /* Previous Press State (when `val == KM_PRESS`). */ + + /** The `type` at the point of the press action. */ + short prev_press_type; + /** + * The location when the key is pressed. + * used to enforce drag threshold & calculate the `direction`. + */ + int prev_press_xy[2]; + /** The `modifier` at the point of the press action. */ + uint8_t prev_press_modifier; + /** The `keymodifier` at the point of the press action. */ + short prev_press_keymodifier; + /** + * The time when the key is pressed, see #PIL_check_seconds_timer. + * Used to detect double-click events. + */ + double prev_press_time; } wmEvent; /** diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index b3ef9b27667..beef74ce2e2 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -1137,7 +1137,7 @@ void WM_gizmo_group_refresh(const bContext *C, wmGizmoGroup *gzgroup) BLI_assert(region->gizmo_map == gzmap); /* Check if the tweak event originated from this region. */ if ((win->eventstate != NULL) && (win->event_queue_check_drag) && - BLI_rcti_isect_pt_v(®ion->winrct, win->eventstate->prev_click_xy)) { + BLI_rcti_isect_pt_v(®ion->winrct, win->eventstate->prev_press_xy)) { /* We need to run refresh again. */ gzgroup->init_flag &= ~WM_GIZMOGROUP_INIT_REFRESH; WM_gizmomap_tag_refresh_drawstep(gzmap, WM_gizmomap_drawstep_from_gizmo_group(gzgroup)); diff --git a/source/blender/windowmanager/intern/wm_event_query.c b/source/blender/windowmanager/intern/wm_event_query.c index c9f83a5d811..9a7d31f8bb8 100644 --- a/source/blender/windowmanager/intern/wm_event_query.c +++ b/source/blender/windowmanager/intern/wm_event_query.c @@ -227,8 +227,8 @@ bool WM_event_is_mouse_drag_or_press(const wmEvent *event) int WM_event_drag_direction(const wmEvent *event) { const int delta[2] = { - event->xy[0] - event->prev_click_xy[0], - event->xy[1] - event->prev_click_xy[1], + event->xy[0] - event->prev_press_xy[0], + event->xy[1] - event->prev_press_xy[1], }; int theta = round_fl_to_int(4.0f * atan2f((float)delta[1], (float)delta[0]) / (float)M_PI); @@ -306,8 +306,8 @@ bool WM_cursor_test_motion_and_update(const int mval[2]) int WM_event_drag_threshold(const struct wmEvent *event) { int drag_threshold; - if (ISMOUSE(event->prev_click_type)) { - BLI_assert(event->prev_click_type != MOUSEMOVE); + if (ISMOUSE(event->prev_press_type)) { + BLI_assert(event->prev_press_type != MOUSEMOVE); /* Using the previous type is important is we want to check the last pressed/released button, * The `event->type` would include #MOUSEMOVE which is always the case when dragging * and does not help us know which threshold to use. */ @@ -340,21 +340,21 @@ bool WM_event_drag_test(const wmEvent *event, const int prev_xy[2]) void WM_event_drag_start_mval(const wmEvent *event, const ARegion *region, int r_mval[2]) { - const int *xy = (event->val == KM_CLICK_DRAG) ? event->prev_click_xy : event->xy; + const int *xy = (event->val == KM_CLICK_DRAG) ? event->prev_press_xy : event->xy; r_mval[0] = xy[0] - region->winrct.xmin; r_mval[1] = xy[1] - region->winrct.ymin; } void WM_event_drag_start_mval_fl(const wmEvent *event, const ARegion *region, float r_mval[2]) { - const int *xy = (event->val == KM_CLICK_DRAG) ? event->prev_click_xy : event->xy; + const int *xy = (event->val == KM_CLICK_DRAG) ? event->prev_press_xy : event->xy; r_mval[0] = xy[0] - region->winrct.xmin; r_mval[1] = xy[1] - region->winrct.ymin; } void WM_event_drag_start_xy(const wmEvent *event, int r_xy[2]) { - copy_v2_v2_int(r_xy, (event->val == KM_CLICK_DRAG) ? event->prev_click_xy : event->xy); + copy_v2_v2_int(r_xy, (event->val == KM_CLICK_DRAG) ? event->prev_press_xy : event->xy); } /** \} */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ee37fc0bea3..a01da3b1fbd 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -154,7 +154,7 @@ wmEvent *WM_event_add_simulate(wmWindow *win, const wmEvent *event_to_add) if (event->val == KM_PRESS) { if ((event->flag & WM_EVENT_IS_REPEAT) == 0) { - copy_v2_v2_int(win->eventstate->prev_click_xy, event->xy); + copy_v2_v2_int(win->eventstate->prev_press_xy, event->xy); } } } @@ -3165,21 +3165,21 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) * in `action` setting #WM_HANDLER_HANDLED, but not #WM_HANDLER_BREAK. */ if ((action & WM_HANDLER_BREAK) == 0 || wm_action_not_handled(action)) { if (win->event_queue_check_drag) { - if (WM_event_drag_test(event, event->prev_click_xy)) { + if (WM_event_drag_test(event, event->prev_press_xy)) { win->event_queue_check_drag_handled = true; const int direction = WM_event_drag_direction(event); /* Intentionally leave `event->xy` as-is, event users are expected to use - * `event->prev_click_xy` if they need to access the drag start location. */ + * `event->prev_press_xy` if they need to access the drag start location. */ const short prev_val = event->val; const short prev_type = event->type; const uint8_t prev_modifier = event->modifier; const short prev_keymodifier = event->keymodifier; event->val = KM_CLICK_DRAG; - event->type = event->prev_click_type; - event->modifier = event->prev_click_modifier; - event->keymodifier = event->prev_click_keymodifier; + event->type = event->prev_press_type; + event->modifier = event->prev_press_modifier; + event->keymodifier = event->prev_press_keymodifier; event->direction = direction; CLOG_INFO(WM_LOG_HANDLERS, 1, "handling PRESS_DRAG"); @@ -3221,8 +3221,8 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) } else if (event->val == KM_RELEASE) { if (win->event_queue_check_drag) { - if ((event->prev_click_type != event->type) && - (ISKEYMODIFIER(event->type) || (event->type == event->prev_click_keymodifier))) { + if ((event->prev_press_type != event->type) && + (ISKEYMODIFIER(event->type) || (event->type == event->prev_press_keymodifier))) { /* Support releasing modifier keys without canceling the drag event, see T89989. */ } else { @@ -3231,12 +3231,12 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) } } - if (event->prev_click_type == event->type) { + if (event->prev_press_type == event->type) { if (event->val == KM_RELEASE) { if (event->prev_val == KM_PRESS) { if (win->event_queue_check_click == true) { - if (WM_event_drag_test(event, event->prev_click_xy)) { + if (WM_event_drag_test(event, event->prev_press_xy)) { win->event_queue_check_click = false; win->event_queue_check_drag = false; } @@ -3245,7 +3245,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) * accurate selecting in case the mouse drifts a little. */ int xy[2] = {UNPACK2(event->xy)}; - copy_v2_v2_int(event->xy, event->prev_click_xy); + copy_v2_v2_int(event->xy, event->prev_press_xy); event->val = KM_CLICK; CLOG_INFO(WM_LOG_HANDLERS, 1, "handling CLICK"); @@ -4691,11 +4691,11 @@ static bool wm_event_is_double_click(const wmEvent *event) { if ((event->type == event->prev_type) && (event->prev_val == KM_RELEASE) && (event->val == KM_PRESS)) { - if (ISMOUSE(event->type) && WM_event_drag_test(event, event->prev_click_xy)) { + if (ISMOUSE(event->type) && WM_event_drag_test(event, event->prev_press_xy)) { /* Pass. */ } else { - if ((PIL_check_seconds_timer() - event->prev_click_time) * 1000 < U.dbl_click_time) { + if ((PIL_check_seconds_timer() - event->prev_press_time) * 1000 < U.dbl_click_time) { return true; } } @@ -4715,12 +4715,12 @@ static void wm_event_prev_values_set(wmEvent *event, wmEvent *event_state) static void wm_event_prev_click_set(wmEvent *event, wmEvent *event_state) { - event->prev_click_time = event_state->prev_click_time = PIL_check_seconds_timer(); - event->prev_click_type = event_state->prev_click_type = event_state->type; - event->prev_click_modifier = event_state->prev_click_modifier = event_state->modifier; - event->prev_click_keymodifier = event_state->prev_click_keymodifier = event_state->keymodifier; - event->prev_click_xy[0] = event_state->prev_click_xy[0] = event_state->xy[0]; - event->prev_click_xy[1] = event_state->prev_click_xy[1] = event_state->xy[1]; + event->prev_press_time = event_state->prev_press_time = PIL_check_seconds_timer(); + event->prev_press_type = event_state->prev_press_type = event_state->type; + event->prev_press_modifier = event_state->prev_press_modifier = event_state->modifier; + event->prev_press_keymodifier = event_state->prev_press_keymodifier = event_state->keymodifier; + event->prev_press_xy[0] = event_state->prev_press_xy[0] = event_state->xy[0]; + event->prev_press_xy[1] = event_state->prev_press_xy[1] = event_state->xy[1]; } static wmEvent *wm_event_add_mousemove(wmWindow *win, const wmEvent *event) |