Event System: drag events now use modifier state on drag start
Now drag & tweak can have modifier keys to be released while dragging. without this, modifier keys needs to be held which is more noticeable for tablet input or whenever the drag threshold is set to a large value. Resolves T89989.
This commit is contained in:
parent
63891f9dad
commit
db4313610c
Notes:
blender-bot
2023-02-13 23:16:02 +01:00
Referenced by commit 90ec634135
, Fix incorrect drag-event threshold when releasing modifiers early
Referenced by issue #101772, Animation Editors: Modifier keys cancel out dragging handles
Referenced by issue #89989, Letting go of Modifier keys will break Tweak Events
|
@ -510,6 +510,10 @@ typedef struct wmGesture {
|
|||
struct wmGesture *next, *prev;
|
||||
/** #wmEvent.type */
|
||||
int event_type;
|
||||
/** #wmEvent.modifier */
|
||||
uint8_t event_modifier;
|
||||
/** #wmEvent.keymodifier */
|
||||
short event_keymodifier;
|
||||
/** Gesture type define. */
|
||||
int type;
|
||||
/** bounds of region to draw gesture within. */
|
||||
|
@ -628,6 +632,11 @@ typedef struct wmEvent {
|
|||
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;
|
||||
|
||||
/**
|
||||
* The previous value of #wmEvent.xy,
|
||||
* Unlike other previous state variables, this is set on any mouse motion.
|
||||
|
|
|
@ -3161,21 +3161,27 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
|
|||
if (WM_event_drag_test(event, event->prev_click_xy)) {
|
||||
win->event_queue_check_drag_handled = true;
|
||||
|
||||
int xy[2] = {UNPACK2(event->xy)};
|
||||
short val = event->val;
|
||||
short type = event->type;
|
||||
const int prev_xy[2] = {UNPACK2(event->xy)};
|
||||
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;
|
||||
|
||||
copy_v2_v2_int(event->xy, event->prev_click_xy);
|
||||
event->val = KM_CLICK_DRAG;
|
||||
event->type = event->prev_type;
|
||||
event->modifier = event->prev_click_modifier;
|
||||
event->keymodifier = event->prev_click_keymodifier;
|
||||
|
||||
CLOG_INFO(WM_LOG_HANDLERS, 1, "handling PRESS_DRAG");
|
||||
|
||||
action |= wm_handlers_do_intern(C, win, event, handlers);
|
||||
|
||||
event->val = val;
|
||||
event->type = type;
|
||||
copy_v2_v2_int(event->xy, xy);
|
||||
event->keymodifier = prev_keymodifier;
|
||||
event->modifier = prev_modifier;
|
||||
event->val = prev_val;
|
||||
event->type = prev_type;
|
||||
copy_v2_v2_int(event->xy, prev_xy);
|
||||
|
||||
win->event_queue_check_click = false;
|
||||
if (!wm_action_not_handled(action)) {
|
||||
|
@ -3205,7 +3211,16 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
|
|||
}
|
||||
}
|
||||
else if (event->val == KM_RELEASE) {
|
||||
win->event_queue_check_drag = false;
|
||||
if (win->event_queue_check_drag) {
|
||||
if ((event->prev_type != event->type) &&
|
||||
(ISKEYMODIFIER(event->type) || (event->type == event->prev_click_keymodifier))) {
|
||||
/* Support releasing modifier keys without canceling the drag event, see T89989.
|
||||
* NOTE: this logic is replicated for tweak gestures. */
|
||||
}
|
||||
else {
|
||||
win->event_queue_check_drag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event->prev_type == event->type) {
|
||||
|
@ -4692,6 +4707,8 @@ 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_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_click_modifier = event_state->prev_click_modifier = event_state->modifier;
|
||||
event->prev_click_keymodifier = event_state->prev_click_keymodifier = event_state->keymodifier;
|
||||
}
|
||||
|
||||
static wmEvent *wm_event_add_mousemove(wmWindow *win, const wmEvent *event)
|
||||
|
|
|
@ -42,6 +42,8 @@ wmGesture *WM_gesture_new(wmWindow *window, const ARegion *region, const wmEvent
|
|||
|
||||
gesture->type = type;
|
||||
gesture->event_type = event->type;
|
||||
gesture->event_modifier = event->modifier;
|
||||
gesture->event_keymodifier = event->keymodifier;
|
||||
gesture->winrct = region->winrct;
|
||||
gesture->user_data.use_free = true; /* Free if userdata is set. */
|
||||
gesture->modal_state = GESTURE_MODAL_NOP;
|
||||
|
|
|
@ -507,6 +507,8 @@ static void gesture_tweak_modal(bContext *C, const wmEvent *event)
|
|||
tevent.type = EVT_TWEAK_M;
|
||||
}
|
||||
tevent.val = val;
|
||||
tevent.modifier = gesture->event_modifier;
|
||||
tevent.keymodifier = gesture->event_keymodifier;
|
||||
tevent.is_repeat = false;
|
||||
/* mouse coords! */
|
||||
|
||||
|
@ -533,7 +535,18 @@ static void gesture_tweak_modal(bContext *C, const wmEvent *event)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (!ISTIMER(event->type) && event->type != EVENT_NONE) {
|
||||
if (ISTIMER(event->type)) {
|
||||
/* Ignore timers. */
|
||||
}
|
||||
else if (event->type == EVENT_NONE) {
|
||||
/* Ignore none events. */
|
||||
}
|
||||
else if ((event->val == KM_RELEASE) &&
|
||||
(ISKEYMODIFIER(event->type) || (event->type == event->prev_click_keymodifier))) {
|
||||
/* Support releasing modifier keys without canceling the drag event, see T89989.
|
||||
* NOTE: this logic is replicated for drag events. */
|
||||
}
|
||||
else {
|
||||
gesture_end = true;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue