Eventos X do mouse inconsistentes para o monitor multitoque Acer T231H

2

Parece um bug

OK, eu acredito que este é um bug no driver xorg evdev, mas como ubuntu-bug para precisas, gentilmente me pediu para trabalhar através dos canais de suporte, eu fui primeiro relatado isso aqui. Enquanto isso, atualizei para o quantal e relatei um bug adequado , mas se alguém da comunidade de suporte tiver uma resposta, isso também não seria errado. (o parágrafo foi editado para se referir ao erro reportado )

Configuração

Este é o Ubuntu 12.04 preciso conectado a um monitor multitoque Acer T231H. Na verdade, eu encontrei isso em mais de uma configuração do sistema operacional, uma delas feita através do debootstrap. Pacotes envolvidos:

  • xserver-xorg-input-evdev 1: 2.7.0-0ubuntu1
  • linux-image - * - genérico 3.2.0-24.39 em um e 3.2.0-25 no outro sistema

Sintoma

Os eventos do mouse como X os envia para os aplicativos são inconsistentes. Isso pode ser depurado usando xev.

O primeiro toque da tela é precedido por um evento MotionNotify que já possui o estado 0x100, ou seja, o botão esquerdo do mouse pressionado. Depois disso, vem um evento ButtonPress, novamente com o estado 0x100, embora esse valor deva indicar o estado dos botões antes do evento. O arrastamento subseqüente está correto, e o ButtonRelease também, mas o bit 0x100 no valor do estado nunca se tornará zero novamente.

Mesmo se eu tiver um mouse comum conectado também, ele informará a cada movimento como se eu estivesse mantendo o botão esquerdo do mouse pressionado. A única cura que consegui encontrar foi reiniciar o servidor X. Juntamente com os eventos ButtonPress e ButtonRelease, este bit constante para o botão esquerdo do mouse equivale a um relatório inconsistente do estado do botão.

Aplicativos Java, por exemplo, irá relatar cada movimento como um obstáculo devido a este problema, com graves implicações para o gerenciamento de foco. Isso torna quase impossível usar partes diferentes do aplicativo, já que o movimento do mouse só será relatado ao componente em que o mouse entrou na janela do aplicativo.

Comparação do comportamento esperado e real

Comportamento esperado:

  1. MotionNotify com o estado 0x000 ao arrastar o mouse comum
  2. MotionNotify com o estado 0x000 para movimentação antes do toque ou nenhum evento
  3. ButtonPress com o estado 0x000 ao tocar na tela
  4. MotionNotify com o estado 0x100 ao arrastar o dedo
  5. ButtonRelease com o estado 0x100 ao levantar o dedo
  6. MotionNotify com o estado 0x000 ao arrastar o mouse comum depois

Comportamento real:

  1. MotionNotify com o estado 0x000 ao arrastar o mouse comum antes do primeiro toque
  2. MotionNotify com estado 0x100 para antes do evento ButtonPress
  3. ButtonPress com o estado 0x100 ao tocar na tela
  4. MotionNotify com o estado 0x100 ao arrastar o dedo
  5. ButtonRelease com o estado 0x100 ao levantar o dedo
  6. MotionNotify com o estado 0x100 ao arrastar o mouse comum depois
por MvG 19.06.2012 / 14:50

1 resposta

2

Resolvi isso sozinho

Análise do erro principal

Eu examinei as fontes do evdev e do servidor x core. Acontece que este bug não está no evdev, afinal, mas no xserver-xorg-core. Um cometer lá (que também é incluído no Xorg upstream ) removido o único trecho de código que já definiu o% sinalizadorTOUCH_END para um evento. Sem esse sinalizador, UpdateDeviceState não removerá o botão do estado , levando assim ao comportamento" O botão está sempre pressionado "da minha pergunta original. Simplesmente reverter esse commit restaurou a funcionalidade principal dos eventos principais, ou seja, o botão foi marcado como liberado logo após o evento ButtonRelease .

Bug menor no evento de imprensa do mouse

No entanto, um problema permanece na saída xev : O evento ButtonPress já tem state 0x100 , mas o estado deve refletir o estado dos botões antes do evento. Isso parece ser devido ao modo como as alterações na propriedade de uma sequência de toques são tratadas. Em um ponto nesse código de gerenciamento de propriedade, o histórico de toque é reproduzido usando TouchEventHistoryReplay , mas o estado interno do dispositivo não está definido como era antes dessa reprodução. Eu ainda não formulei um patch para isso. Quando o fizer, irei anexá-lo ao relatório de erros . Eu considero esta questão aqui respondida mesmo sem um patch para esse ponto menor, já que é uma questão separada.

Como depurar isso

No caso de alguém ler isto com um problema similar: Eu considerei usar o gdb, mas eu estava longe de ter certeza se eu seria capaz de mudar vt corretamente se o servidor X estivesse parado no depurador, e eu não fiz ter um servidor ssh de trabalho configurado nessa máquina. Então eu usei um dos mais antigos recursos de depuração de todos os tempos e espalhei generosamente ErrorF em todo o código, Xi / exevents.c em particular. Eu então recompilei o código (que eu tinha inicialmente compilado usando debuild ) sem instalá-lo, e executei o binário compilado ( build-main/hw/xfree86/Xorg ) como root assim:

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

Isto recompila o código (demora até mesmo para uma pequena modificação, então parece que o gerenciamento de dependências nos makefiles está abaixo do ideal, mas eu não tive vontade de cavar isso também). Então, depois de se tornar root, ele inicia o novo servidor X e inicia o openbox no servidor alguns instantes depois. Note que você estará executando o openbox como root, então isso é apenas para testes.

    
por MvG 26.06.2012 / 08:40