Fix T53491: Absolute tablet motion detection fails
authorCampbell Barton <ideasman42@gmail.com>
Wed, 10 Jan 2018 01:25:20 +0000 (12:25 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 10 Jan 2018 01:41:45 +0000 (12:41 +1100)
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.

source/blender/editors/space_view3d/view3d_walk.c
source/blender/makesrna/intern/rna_wm.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_cursors.c
source/blender/windowmanager/intern/wm_event_system.c

index 9464f332d399f51e288bbe2ccc3c976937542200..f780ca35f30d53bce07b00b1c6f227b36d6e96d8 100644 (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);
index 23ad51be343c71ecd101cc161e080bf037eb17c3..3ca46fea7b6e17d3f097914ebd00c558971a5877 100644 (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);
index 96ed179c8f4fa27c878273b696ade1e2460a16fd..9dc4b35abb4fa39de88ac095fdc8d0574bdbc1c8 100644 (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);
 
index 6c47d61c535538900c80de813a655c86959a9b50..cd78a519dbf700455993c130408686d2d15aadbf 100644 (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;
 
index d4c3928bd6cbaabd5eb27cbf1d7dab08fda1691f..ad5e83ceda72dad8abcafb45af908549517c4abc 100644 (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;
                }
index 8f0b5de0cde83442f719ed9fc08f7074032e911a..ed56586711d562f683edfaff0b17b9436784d88f 100644 (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;