Fix T53491: Absolute tablet motion detection fails

When using a tablet, detecting absolute motion only worked
when activating a tool with the tablet.

Pressing Enter to run a tool for e.g. would use relative motion.

Now store is_motion_absolute in the event,
set for new events based on the most recent motion events.
This commit is contained in:
Campbell Barton 2018-01-10 12:25:20 +11:00
parent 9aada45e52
commit fdd3d969a6
Notes: blender-bot 2023-02-14 10:37:49 +01:00
Referenced by issue #53683, 2.79a release
Referenced by issue #53491, Continuous Grab with pen tablet produces strange results when pen is lifted off tablet (using enter to start operation instead of clicking with tablet pen) and then moved outside of the view area
6 changed files with 41 additions and 33 deletions

View File

@ -699,7 +699,7 @@ static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent
return;
}
if ((walk->is_cursor_absolute == false) && WM_event_is_absolute(event)) {
if ((walk->is_cursor_absolute == false) && event->is_motion_absolute) {
walk->is_cursor_absolute = true;
copy_v2_v2_int(walk->prev_mval, event->mval);
copy_v2_v2_int(walk->center_mval, event->mval);

View File

@ -1766,6 +1766,11 @@ static void rna_def_event(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_Event_is_tablet_get", NULL);
RNA_def_property_ui_text(prop, "Tablet Pressure", "The pressure of the tablet or 1.0 if no tablet present");
prop = RNA_def_property(srna, "is_mouse_absolute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "is_motion_absolute", 1);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Absolute Motion", "The last motion event was an absolute an input");
/* modifiers */
prop = RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shift", 1);

View File

@ -188,7 +188,6 @@ struct wmEventHandler *WM_event_add_dropbox_handler(ListBase *handlers, ListBase
/* mouse */
void WM_event_add_mousemove(struct bContext *C);
bool WM_event_is_modal_tweak_exit(const struct wmEvent *event, int tweak_event);
bool WM_event_is_absolute(const struct wmEvent *event);
bool WM_event_is_last_mousemove(const struct wmEvent *event);
#ifdef WITH_INPUT_NDOF
@ -206,11 +205,11 @@ void WM_report_banner_show(void);
void WM_report(ReportType type, const char *message);
void WM_reportf(ReportType type, const char *format, ...) ATTR_PRINTF_FORMAT(2, 3);
void wm_event_add_ex(
struct wmEvent *wm_event_add_ex(
struct wmWindow *win, const struct wmEvent *event_to_add,
const struct wmEvent *event_to_add_after)
ATTR_NONNULL(1, 2);
void wm_event_add(
struct wmEvent *wm_event_add(
struct wmWindow *win, const struct wmEvent *event_to_add)
ATTR_NONNULL(1, 2);

View File

@ -461,8 +461,9 @@ typedef struct wmEvent {
short keymodifier; /* rawkey modifier */
/* set in case a KM_PRESS went by unhandled */
short check_click;
char check_click;
char is_motion_absolute;
/* keymap item, set by handler (weak?) */
const char *keymap_idname;

View File

@ -213,13 +213,10 @@ void WM_cursor_grab_enable(wmWindow *win, bool wrap, bool hide, int bounds[4])
}
if ((G.debug & G_DEBUG) == 0) {
if (win->ghostwin) {
const GHOST_TabletData *tabletdata = GHOST_GetTabletData(win->ghostwin);
/* Note: There is no tabletdata on Windows if no tablet device is connected. */
if (!tabletdata)
GHOST_SetCursorGrab(win->ghostwin, mode, bounds, NULL);
else if (tabletdata->Active == GHOST_kTabletModeNone)
if (win->eventstate->is_motion_absolute == false) {
GHOST_SetCursorGrab(win->ghostwin, mode, bounds, NULL);
}
win->grabcursor = mode;
}

View File

@ -94,7 +94,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA
/* ************ event management ************** */
void wm_event_add_ex(wmWindow *win, const wmEvent *event_to_add, const wmEvent *event_to_add_after)
wmEvent *wm_event_add_ex(wmWindow *win, const wmEvent *event_to_add, const wmEvent *event_to_add_after)
{
wmEvent *event = MEM_mallocN(sizeof(wmEvent), "wmEvent");
@ -102,6 +102,13 @@ void wm_event_add_ex(wmWindow *win, const wmEvent *event_to_add, const wmEvent *
update_tablet_data(win, event);
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
/* We could have a preference to support relative tablet motion (we can't detect that). */
event->is_motion_absolute = (
(event->tablet_data != NULL) &&
(event->tablet_data->Active != GHOST_kTabletModeNone));
}
if (event_to_add_after == NULL) {
BLI_addtail(&win->queue, event);
}
@ -109,11 +116,12 @@ void wm_event_add_ex(wmWindow *win, const wmEvent *event_to_add, const wmEvent *
/* note, strictly speaking this breaks const-correctness, however we're only changing 'next' member */
BLI_insertlinkafter(&win->queue, (void *)event_to_add_after, event);
}
return event;
}
void wm_event_add(wmWindow *win, const wmEvent *event_to_add)
wmEvent *wm_event_add(wmWindow *win, const wmEvent *event_to_add)
{
wm_event_add_ex(win, event_to_add, NULL);
return wm_event_add_ex(win, event_to_add, NULL);
}
void wm_event_free(wmEvent *event)
@ -624,11 +632,6 @@ void WM_report_banner_show(void)
wm_reports->reporttimer->customdata = rti;
}
bool WM_event_is_absolute(const wmEvent *event)
{
return (event->tablet_data != NULL);
}
bool WM_event_is_last_mousemove(const wmEvent *event)
{
while ((event = event->next)) {
@ -3196,7 +3199,7 @@ static bool wm_event_is_double_click(wmEvent *event, const wmEvent *event_state)
return false;
}
static void wm_event_add_mousemove(wmWindow *win, const wmEvent *event)
static wmEvent *wm_event_add_mousemove(wmWindow *win, const wmEvent *event)
{
wmEvent *event_last = win->queue.last;
@ -3206,16 +3209,13 @@ static void wm_event_add_mousemove(wmWindow *win, const wmEvent *event)
if (event_last && event_last->type == MOUSEMOVE)
event_last->type = INBETWEEN_MOUSEMOVE;
wm_event_add(win, event);
{
wmEvent *event_new = win->queue.last;
if (event_last == NULL) {
event_last = win->eventstate;
}
copy_v2_v2_int(&event_new->prevx, &event_last->x);
wmEvent *event_new = wm_event_add(win, event);
if (event_last == NULL) {
event_last = win->eventstate;
}
copy_v2_v2_int(&event_new->prevx, &event_last->x);
return event_new;
}
/* windows store own event queues, no bContext here */
@ -3245,8 +3245,11 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
wm_stereo3d_mouse_offset_apply(win, &event.x);
event.type = MOUSEMOVE;
wm_event_add_mousemove(win, &event);
copy_v2_v2_int(&evt->x, &event.x);
{
wmEvent *event_new = wm_event_add_mousemove(win, &event);
copy_v2_v2_int(&evt->x, &event_new->x);
evt->is_motion_absolute = event_new->is_motion_absolute;
}
/* also add to other window if event is there, this makes overdraws disappear nicely */
/* it remaps mousecoord to other window in event */
@ -3258,8 +3261,11 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
copy_v2_v2_int(&oevent.x, &event.x);
oevent.type = MOUSEMOVE;
wm_event_add_mousemove(owin, &oevent);
copy_v2_v2_int(&oevt->x, &oevent.x);
{
wmEvent *event_new = wm_event_add_mousemove(owin, &oevent);
copy_v2_v2_int(&oevt->x, &event_new->x);
oevt->is_motion_absolute = event_new->is_motion_absolute;
}
}
break;