Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/windowmanager/WM_types.h9
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c31
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c2
-rw-r--r--source/blender/windowmanager/intern/wm_gesture_ops.c15
4 files changed, 49 insertions, 8 deletions
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 2f431bcd208..e9f12287d29 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -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.
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 326b8c167b8..6753978eece 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -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)
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 581c5f8a198..86ada4aaf2a 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -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;
diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c
index 2a27a8df411..d7e62d549d0 100644
--- a/source/blender/windowmanager/intern/wm_gesture_ops.c
+++ b/source/blender/windowmanager/intern/wm_gesture_ops.c
@@ -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;