Несовместимые события мыши X для мультитач-монитора Acer T231H
Выглядит как ошибка
Хорошо, я считаю, что это ошибка в драйвере xorg evdev, но, как точный ubuntu-bug, любезно попросил меня поработать через каналы поддержки, я сначала пошел и сообщил об этом здесь. Тем временем я обновился до количественного и сообщил об ошибке, но если кто-то из сообщества поддержки должен иметь ответ, это тоже не сработает. (Параграф был отредактирован, чтобы ссылаться на сообщенную ошибку)
Настроить
Это Ubuntu 12.04, точно подключенный к мультитач-монитору Acer T231H. На самом деле, я столкнулся с этим на более чем одной установке ОС, одна из которых была выполнена через debootstrap. Пакеты участвуют:
- xserver-xorg-input-evdev 1: 2.7.0-0ubuntu1
- linux-image - * - универсальный 3.2.0-24.39 в одной и 3.2.0-25 в другой системе
симптом
События мыши, когда X отправляет их приложениям, не соответствуют требованиям. Это можно отладить с помощью xev.
Первому касанию экрана предшествует событие MotionNotify, которое уже имеет состояние 0x100, т. Е. Нажатие левой кнопки мыши. После этого наступает событие ButtonPress, снова с состоянием 0x100, хотя это значение должно указывать состояние кнопок до того, как событие произошло. С последующим перетаскиванием все в порядке, и ButtonRelease также, но бит 0x100 в значении состояния никогда не станет снова нулевым.
Даже если у меня подключена и обычная мышь, отныне она будет сообщать о каждом движении, как будто я удерживаю левую кнопку мыши нажатой. Единственное лекарство, которое я смог найти, это перезапустить X-сервер. Вместе с событиями ButtonPress и ButtonRelease этот константный бит для левой кнопки мыши составляет непоследовательный отчет о состоянии кнопки.
Например, Java-приложения будут сообщать о каждом движении как перетаскивание из-за этой проблемы с серьезными последствиями для управления фокусом. Это делает практически невозможным использование различных частей приложения, поскольку о движении мыши будет сообщено только тому компоненту, где мышь вошла в окно приложения.
Сравнение ожидаемого и фактического поведения
Ожидаемое поведение:
- MotionNotify с состоянием 0x000 при перетаскивании обычной мыши
- MotionNotify с состоянием 0x000 для перемещения до касания или без событий вообще
- ButtonPress с состоянием 0x000 при касании экрана
- MotionNotify с состоянием 0x100 при перетаскивании пальца
- Кнопка отпустить с состоянием 0x100 при поднятии пальца
- MotionNotify с состоянием 0x000 при перетаскивании обычной мыши впоследствии
Фактическое поведение:
- MotionNotify с состоянием 0x000 при перетаскивании обычной мыши до первого касания
- MotionNotify с состоянием 0x100 для до события ButtonPress
- ButtonPress с состоянием 0x100 при касании экрана
- MotionNotify с состоянием 0x100 при перетаскивании пальца
- Кнопка отпустить с состоянием 0x100 при поднятии пальца
- MotionNotify с состоянием 0x100 при перетаскивании обычной мыши впоследствии
1 ответ
Решил это сам
Анализ основной ошибки
Я копался в источниках evdev и core x server. Оказывается, что эта ошибка, в конце концов, не в evdev, а в xserver-xorg-core. Коммит там (который также включен в исходный Xorg) удалил единственный фрагмент кода, который когда-либо устанавливал TOUCH_END флаг для события. Без этого флага UpdateDeviceState не удалит кнопку из состояния, что приведет к поведению "кнопка всегда нажата" из моего первоначального вопроса. Простой возврат этого коммита восстановил основные функциональные возможности основных событий, т. Е. Кнопка была помечена как отпущенная сразу после ButtonRelease событие.
Небольшая ошибка при нажатии мыши
Одна проблема остается в xev выход, хотя: ButtonPress событие уже имеет state 0x100, но состояние должно отражать состояние кнопок мыши до того, как произошло событие. Похоже, это связано с тем, как обрабатываются изменения владельца последовательности касаний. В какой-то момент в этом коде управления владением история касаний воспроизводится с использованием TouchEventHistoryReplay, но внутреннее состояние устройства не установлено на то, что было до этого воспроизведения. Я еще не сформулировал патч для этого. Когда я это сделаю, я приложу его к сообщению об ошибке. Я считаю, что на этот вопрос здесь ответили даже без заплатки по этому второстепенному вопросу, поскольку это отдельная проблема.
Как отладить это
В случае, если кто-то читает это с похожей проблемой: я подумал об использовании gdb, но я был далеко не уверен, смогу ли я правильно переключить vt, если X-сервер был остановлен в отладчике, и у меня не было работающего Сервер ssh настроен на этом компьютере. Так что я использовал одну из самых старых и отлаженных средств отладки ErrorF звонит по всему коду, в частности Xi / exevents.c. Затем я перекомпилировал код (который я изначально скомпилировал с помощью debuild), не устанавливая его, и запустил скомпилированный двоичный файл (build-main/hw/xfree86/Xorg) как root, как это:
$ make -C build-main
$ sudo -s
# apt-get install openbox
# ( sleep 3; DISPLAY=:1 exec openbox; ) & build-main/hw/xfree86/Xorg :1
Это перекомпилирует код (требуются годы даже для незначительной модификации, поэтому кажется, что управление зависимостями в make-файлах является неоптимальным, но я также не хотел копаться в этом). Затем, став пользователем root, он запускает новый X-сервер и через несколько минут запускает openbox на этом сервере. Обратите внимание, что вы будете запускать openbox как root, так что это только для тестирования.