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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user