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/intern
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-01-16 22:05:17 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-01-16 22:05:17 +0400
commitcda2b7db0fe904538ffa42ae4f63527f3defc3be (patch)
tree6d2cb917c711bfb91345d9c454f5a76b352ab3a8 /intern
parent44115a74159651902ad9c88d9f5dd577aa97e3fd (diff)
fix for glitch in X11 with tablets.
Notices this while using continuous-grab, since this is disabled when the tablet is being used. Quite often I would use the tablet then drag a button with the mouse but blender would still have the tablet enabled. This error would cause other parts of blender to behave incorrectly too since wmEvents would have wmTabletData set, operators check for this in some cases. The problem was blender didn't reliably get ProximityOut events, eg: moving the cursor outside the window with the tablet, then back over the window with the mouse - meant blender didn't get a 'ProximityOut' event and would keep the active stylus value set. For now, when the processing events and the active stylus is set, run a check that the tablet is still in proximity.
Diffstat (limited to 'intern')
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp52
1 files changed, 51 insertions, 1 deletions
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index b7715de665d..f5c31c93335 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -518,6 +518,40 @@ static void setTabletMode(GHOST_SystemX11 *system, GHOST_WindowX11 *window, XID
}
#endif /* WITH_X11_XINPUT */
+#ifdef WITH_X11_XINPUT
+static bool checkTabletProximity(Display *display, XDevice *device)
+{
+ /* see: state.c from xinput, to get more data out of the device */
+ XDeviceState *state;
+
+ state = XQueryDeviceState(display, device);
+
+ if (state) {
+ XInputClass *cls = state->data;
+ // printf("%d class%s :\n", state->num_classes,
+ // (state->num_classes > 1) ? "es" : "");
+ for(int loop=0; loop < state->num_classes; loop++) {
+ switch(cls->c_class) {
+ case ValuatorClass:
+ XValuatorState *val_state = (XValuatorState *) cls;
+ // printf("ValuatorClass Mode=%s Proximity=%s\n",
+ // val_state->mode & 1 ? "Absolute" : "Relative",
+ // val_state->mode & 2 ? "Out" : "In");
+
+ if ((val_state->mode & 2) == 0) {
+ XFreeDeviceState(state);
+ return true;
+ }
+ break;
+ }
+ cls = (XInputClass *) ((char *) cls + cls->length);
+ }
+ XFreeDeviceState(state);
+ }
+ return false;
+}
+#endif /* WITH_X11_XINPUT */
+
void
GHOST_SystemX11::processEvent(XEvent *xe)
{
@@ -527,7 +561,23 @@ GHOST_SystemX11::processEvent(XEvent *xe)
if (!window) {
return;
}
-
+
+#ifdef WITH_X11_XINPUT
+ /* Proximity-Out Events are not reliable, if the tablet is active - check on each event
+ * this adds a little overhead but only while the tablet is in use.
+ * in the futire we could have a ghost call window->CheckTabletProximity()
+ * but for now enough parts of the code are checking 'Active'
+ * - campbell */
+ if (window->GetTabletData()->Active != GHOST_kTabletModeNone) {
+ if (checkTabletProximity(xe->xany.display, m_xtablet.StylusDevice) == false &&
+ checkTabletProximity(xe->xany.display, m_xtablet.EraserDevice) == false)
+ {
+ // printf("proximity disable\n");
+ window->GetTabletData()->Active = GHOST_kTabletModeNone;
+ }
+ }
+#endif /* WITH_X11_XINPUT */
+
switch (xe->type) {
case Expose:
{