web-dev-qa-db-fra.com

Événements X de souris incohérents pour le moniteur tactile multipoint Acer T231H

Ressemble à un bug

OK, je crois que c'est un bogue dans le pilote xorg evdev, mais comme ubuntu-bug pour la précision m'a si gentiment demandé de travailler à travers les canaux de support, je suis d'abord allé le signaler ici. En attendant, je suis passé à quantal et j'ai signalé un bon bug , mais si quelqu'un de la communauté de support devait avoir une réponse, cela ne serait pas non plus mal. (Le paragraphe a été modifié pour faire référence au bug signalé )

Installer

Il s'agit d'Ubuntu 12.04 précis connecté à un moniteur multitouch Acer T231H. En fait, je l'ai rencontré sur plusieurs configurations de système d'exploitation, l'une d'entre elles via le débootstrap. Forfaits impliqués:

  • xserver-xorg-input-evdev 1: 2.7.0-0ubuntu1
  • linux-image - * - générique 3.2.0-24.39 sur l'un et 3.2.0-25 sur l'autre système

Symptôme

Les événements de souris tels que X les envoie aux applications sont incohérents. Cela peut être débogué à l'aide de xev.

La première touche de l'écran est précédée d'un événement MotionNotify qui a déjà l'état 0x100, c'est-à-dire le bouton gauche de la souris enfoncé. Après cela vient un événement ButtonPress, à nouveau avec l'état 0x100 bien que cette valeur devrait indiquer l'état des boutons avant l'événement s'est produit. Le glissement ultérieur est correct, ainsi que le ButtonRelease, mais le bit 0x100 dans la valeur d'état ne redeviendra jamais nul.

Même si j'ai une souris ordinaire connectée, elle signalera désormais chaque mouvement comme si je maintenais le bouton gauche de la souris enfoncé. Le seul remède que j'ai pu trouver était de redémarrer le serveur X. Avec les événements ButtonPress et ButtonRelease, ce bit constant pour le bouton gauche de la souris équivaut à un rapport incohérent de l'état du bouton.

Applications Java, par ex. signalera chaque mouvement comme un frein dû à ce problème, avec de graves implications pour la gestion de la mise au point. Cela rend l'utilisation de différentes parties de l'application presque impossible, car le mouvement de la souris ne sera signalé qu'au composant où la souris est entrée dans la fenêtre de l'application.

Comparaison des comportements attendus et réels

Comportement attendu:

  1. MotionNotify avec état 0x000 lors du déplacement de la souris ordinaire
  2. MotionNotify avec état 0x000 pour le déplacement avant le toucher, ou aucun événement du tout
  3. Bouton Appuyez sur avec l'état 0x000 lorsque vous touchez l'écran
  4. MotionNotify avec l'état 0x100 tout en faisant glisser le doigt
  5. Relâchez le bouton avec l'état 0x100 lorsque vous soulevez le doigt
  6. MotionNotify avec état 0x000 lors du glissement de la souris ordinaire par la suite

Comportement réel:

  1. MotionNotify avec l'état 0x000 lors du déplacement de la souris ordinaire avant le premier contact
  2. MotionNotify avec état 0x100 pour avant l'événement ButtonPress
  3. ButtonPress avec état 0x100 en touchant l'écran
  4. MotionNotify avec l'état 0x100 tout en faisant glisser le doigt
  5. Relâchez le bouton avec l'état 0x100 lorsque vous soulevez le doigt
  6. MotionNotify avec état 0x100 lors du déplacement de la souris ordinaire par la suite
2
MvG

Résolu cela moi-même

Analyse du bug principal

J'ai fouillé les sources d'evdev et du serveur core x. Il s'avère que ce bogue n'est pas dans evdev après tout, mais dans xserver-xorg-core. Un commit là (qui est aussi inclus dans l'amont Xorg ) a supprimé le seul morceau de code qui ait jamais défini le TOUCH_END drapeau pour un événement. Sans cet indicateur, UpdateDeviceStatene supprimera pas le bouton de l'état , conduisant ainsi au comportement "Le bouton est toujours enfoncé" de ma question d'origine. En revenant simplement à la validation, la fonctionnalité principale des événements principaux restaurée, c.-à-d. Que le bouton a été marqué comme étant relâché juste après l'événement ButtonRelease.

Événement de bogue mineur sur la souris

Un problème subsiste cependant dans la sortie xev: l'événement ButtonPress a déjà state 0x100, mais l'état doit refléter l'état des boutons de la souris avant l'événement s'est produit. Cela semble être dû à la façon dont les modifications apportées à la propriété d'une séquence tactile sont gérées. À n point dans ce code de gestion de propriété, l'historique tactile est relu à l'aide de TouchEventHistoryReplay, mais l'état interne de l'appareil n'est pas défini comme il était avant cette relecture. Je n'ai pas encore formulé de patch pour cela. Quand je le ferai, je le joindrai au rapport de bogue . Je considère que cette question répond ici même sans patch pour ce point mineur, car il s'agit d'un problème distinct.

Comment déboguer cela

Au cas où quelqu'un lirait ceci avec un problème similaire: j'avais envisagé d'utiliser gdb, mais j'étais loin d'être certain de pouvoir basculer correctement vt si le serveur X était arrêté dans le débogueur, et je n'avais pas de travail serveur ssh configuré sur cette machine. J'ai donc utilisé l'une des plus anciennes aides au débogage de tous les temps et des appels ErrorF généreusement dispersés partout dans le code, Xi/exevents.c en particulier. J'ai ensuite recompilé le code (que j'avais initialement compilé en utilisant debuild ) sans l'installer, et j'ai exécuté le binaire compilé (build-main/hw/xfree86/Xorg) en tant que root comme ceci:

$ make -C build-main
$ Sudo -s
# apt-get install openbox
# ( sleep 3; DISPLAY=:1 exec openbox; ) & build-main/hw/xfree86/Xorg :1

Cela recompile le code (prend du temps même pour une modification mineure, il semble donc que la gestion des dépendances dans les makefiles soit sous-optimale, mais je n'avais pas envie de creuser aussi). Puis, après être devenu root, il démarre le nouveau serveur X et démarre openbox sur ce serveur quelques instants plus tard. Notez que vous exécuterez openbox en tant que root, c'est donc strictement pour les tests uniquement.

2
MvG