2016-06-29 39 views
0

Ich versuche, Schlüsselereignisse zu senden, indem ich ein XKeyEvent erzeuge und es mit XSendEvent (inspiriert von this post) sende. Die XKeyEvents werden wie folgt hergestellt:XSendEvent ändert den Status des Modifizierungsschlüssels nicht

XKeyEvent createKeyEvent(Display *display, Window win, Window winRoot, _Bool press, int keycode, int modifiers) { 
    XKeyEvent event; 

    event.display  = display; 
    event.window  = win; 
    event.root  = winRoot; 
    event.subwindow = None; 
    event.time  = CurrentTime; 
    event.x   = 1; 
    event.y   = 1; 
    event.x_root  = 1; 
    event.y_root  = 1; 
    event.same_screen = True; 
    event.keycode  = keycode; 
    event.state  = modifiers; 

    if (press) { 
     event.type = KeyPress; 
    } else { 
     event.type = KeyRelease; 
    } 

    return event; 
} 

Dann werden sie mit geschickt XSendEvent(event.display, event.window, 1, KeyPressMask, (XEvent *)&event);

Die wichtigsten Ereignisse werden gesendet und das Zielprogramm erhält sie (Buchstaben eingegeben werden, die Pfeiltasten funktionieren etc.). Es treten jedoch Probleme mit Zusatztasten auf. Nehmen wir an, das Programm sendet ein Key-down-Ereignis für die opt/alt-Taste. In diesem Szenario wird der Text in der Menüleiste unterstrichen, bis ein Key-up-Ereignis gesendet wird (das anzeigt, dass der X-Server das Key-Down-Ereignis empfangen und verarbeitet hat).

Wenn Sie jedoch den aktuellen Status der Zusatztasten abrufen, werden die Zusatztasten anscheinend überhaupt nicht gedrückt. Wenn XQueryPointer(self->display, winFocus, &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &keyboard_state_mask); aufgerufen wird, ist die keyboard_state_mask 0. Das Überprüfen der Tastatur mit xev gibt das gleiche Ergebnis. Wenn Sie die Modifizierertasten physisch drücken, ändert sich die Statusmaske sowohl in xev als auch in meinem Code.

Wie ändere ich den aktuellen Modifier-Key-Zustand richtig?

+0

Es ist mir nicht ganz klar, aber erwarten Sie, dass die X11-Server-Ansicht des Status der Tastaturmodifikatoren von den von Ihnen gesendeten Ereignissen beeinflusst wird? –

+0

Ja, ich erwarte, dass das passiert. –

Antwort

0

Das Problem wurde behoben, indem die Methode int XTestFakeButtonEvent(display, button, is_press, delay) aus der Bibliothek <X11/extensions/XTest.h> verwendet wurde. Aus irgendeinem Grund bewirkt dies, dass sich der Keyboard-Modifier-Status ändert, wenn eine Modifier-Taste gesendet wird (wie ich es wollte), während dies bei der oben genannten Methode nicht der Fall ist.

0

Von xsendevent Manpages:

„Die Inhalte der Veranstaltung sind ansonsten unverändert und ohne Überprüfung durch den X-Server außer außer in dem weitergeleiteten Ereignisse send_event auf True zu zwingen und die Seriennummer für den Fall richtig einzustellen. "

Ich gehe davon aus, dass Sie createKeyEvent() aus der folgenden Stelle kopiert: http://www.doctort.org/adam/nerd-notes/x11-fake-keypress-event.html

Und wenn Sie auch kopiert die Art und Weise diese Funktion aufgerufen wird:

createKeyEvent (Display, winFocus, winroot, falsch, KEYCODE, 0);

dann macht es Sinn, dass "Modifikator" auf nichts eingestellt ist, da das letzte Argument "0" ist. Gemäß der Dokumentation müssen Sie den Modifikationsstatus selbst festlegen.

Ich habe diese Information nicht überprüft. Wenn es nicht wie dokumentiert funktioniert, könnte es sich um einen Dokumentationsfehler oder einen Fehler in der X Server-Implementierung handeln.