voglio implementare accordi chiave su una tastiera normale e ho pensato di usare python xlib. affinché funzioni, il programma deve ingoiare globalmente tutti gli eventi chiave e solo in un secondo momento consentirne il passaggio.acquisisce globalmente, ignora e invia keyjevents con python xlib, riconosce l'input falso
il mio test corrente prende semplicemente il tasto "1". se questo tasto viene premuto, chiama un gestore che invia "x" alla finestra focalizzata tramite xtest.fake_input. perché sto solo prendendo il tasto "1", non dovrebbe esserci un problema, giusto? ma in qualche modo il gestore viene chiamato di nuovo, perché "x" è stato premuto. infatti, nel momento in cui digito "1" il programma sta ascoltando tutte le chiavi. questo potrebbe avere qualcosa a che fare con chiamando
display.allow_events(X.ReplayKeyboard, X.CurrentTime)
dopo aver toccato un evento, ma se non faccio questo, tutto si blocca.
per il programma finale il cambiamento nel comportamento di ascolto non è veramente rilevante, ma devo essere in grado di distinguere gli eventi falsi dagli eventi utente. per fare questo sto solo facendo avanzare velocemente display.next_event(), ma questo non è l'ideale, perché l'utente potrebbe digitare in quel momento esatto e di quei tasti che andrebbero persi.
ho provato rilasciando il KeyGrab durante la trasmissione e lo svuotamento del EventQueue via
display.flush()
display.sync()
ma che non fa nulla.
quindi, qualche idea su come riconoscere o ignorare gli eventi di input falsi e perché sto improvvisamente ascoltando tutti i tasti premuti (e le versioni)?
xlib è molto frustrante.
from Xlib.display import Display
import Xlib
from Xlib import X
import Xlib.XK
import sys
import signal
display = None
root = None
def handle_event(aEvent):
print "handle!"
send_key("x")
def send_key(emulated_key):
global display,root
print "send key"
# ungrabbing doesnt help
root.ungrab_key(10,X.AnyModifier)
window = display.get_input_focus()._data["focus"]
# Generate the correct keycode
keysym = Xlib.XK.string_to_keysym(emulated_key)
keycode = display.keysym_to_keycode(keysym)
# Send a fake keypress via xtestaaa
Xlib.ext.xtest.fake_input(window, Xlib.X.KeyPress, keycode)
Xlib.ext.xtest.fake_input(window, Xlib.X.KeyRelease, keycode)
display.flush()
display.sync()
# fast forward those two events,this seems a bit hacky,
# what if theres another keyevent coming in at that exact time?
while display.pending_events():
display.next_event()
#
root.grab_key(10, X.AnyModifier, True,X.GrabModeSync, X.GrabModeSync)
def main():
# current display
global display,root
display = Display()
root = display.screen().root
# we tell the X server we want to catch keyPress event
root.change_attributes(event_mask = X.KeyPressMask)
# just grab the "1"-key for now
root.grab_key(10, X.AnyModifier, True,X.GrabModeSync, X.GrabModeSync)
# while experimenting everything could freeze, so exit after 10 seconds
signal.signal(signal.SIGALRM, lambda a,b:sys.exit(1))
signal.alarm(10)
while 1:
event = display.next_event()
print "event"
#if i dont call this, the whole thing freezes
display.allow_events(X.ReplayKeyboard, X.CurrentTime)
handle_event(event)
if __name__ == '__main__':
main()
Questo sembra bloccarsi in silenzio dopo un certo tempo o dopo il mashing 1 e altri tasti con repliche chiave (non può dire quale). Anche un altro utente ha segnalato questo, ma il suo commento è stato cancellato perché è stato pubblicato come risposta. – ninjagecko
@ninjagecko Ho lo stesso problema. Inoltre non ho capito quale combinazione di tasti. Ma ho fallito dopo 20 minuti e dopo un minuto e mezzo. Sembra essere casuale o dipendente dall'uso della tastiera/del mouse. – Munchhausen