Tastatureingaben an aktives Fenster senden
- Programie
- Beiträge: 1280
- Registriert: 06.08.2005 22:56
- Computerausstattung: https://www.sysprofile.de/id160800
- Wohnort: Gernsbach
- Kontaktdaten:
Tastatureingaben an aktives Fenster senden
In meinem aktuellen PB Projekt Keyboard Mapper moechte ich implementieren, dass Tastatureingaben in das aktuell aktive Fenster einer fremden Anwendung gesendet werden. Unter Windows funktioniert das mit keybd_event_() aus der WinAPI. Gibt es unter Linux eine vergleichbare Funktion?
Ich moechte zwei Varianten implementieren: Senden von einfachen Tastatureingaben und Senden eines kompletten Strings (z.B. per Clipboard + Ctrl+V im aktiven Fenster).
Hat jemand eine Idee wie man das in PB unter Linux implementieren kann?
Ich moechte zwei Varianten implementieren: Senden von einfachen Tastatureingaben und Senden eines kompletten Strings (z.B. per Clipboard + Ctrl+V im aktiven Fenster).
Hat jemand eine Idee wie man das in PB unter Linux implementieren kann?
Re: Tastatureingaben an aktives Fenster senden
Es gibt gdk_event_put_(). Damit kannst du auch Keycodes simulieren. Leider konnte ich in diesem Forum kein Beispielcode finden.
- Programie
- Beiträge: 1280
- Registriert: 06.08.2005 22:56
- Computerausstattung: https://www.sysprofile.de/id160800
- Wohnort: Gernsbach
- Kontaktdaten:
Re: Tastatureingaben an aktives Fenster senden
Hi Programie,
da Linux hier sehr widerborstig ist, schau Dir vielleicht mal wmctrl oder (vielleicht noch geeigneter) xdotool für Linux X11 an.
Kann sein dass Du hier schneller ans Ziel kommst.Gruß, Charly
da Linux hier sehr widerborstig ist, schau Dir vielleicht mal wmctrl oder (vielleicht noch geeigneter) xdotool für Linux X11 an.
Kann sein dass Du hier schneller ans Ziel kommst.
Code: Alles auswählen
;Ein paar Links zu xdotool ...
;http://manpages.ubuntu.com/manpages/xenial/man1/xdotool.1.html
;https://www.linux.org/threads/xdotool-keyboard.10528/
;http://xmodulo.com/simulate-key-press-mouse-movement-linux.html
Delay(2000)
;Klicke auf ein Fremdfenster ...
; Debug RunProgram ("xdotool", "getactivewindow key ctrl+Q", ""); schließt (meist) das aktive Fenster
Debug RunProgram ("xdotool", "getactivewindow key ctrl+Down", ""); scrollt (meist) das aktive Fenster nach unten
PureBasic Linux-API-Library: http://www.chabba.de
- Programie
- Beiträge: 1280
- Registriert: 06.08.2005 22:56
- Computerausstattung: https://www.sysprofile.de/id160800
- Wohnort: Gernsbach
- Kontaktdaten:
Re: Tastatureingaben an aktives Fenster senden
OK, einen Aufruf von xdotool oder so mit RunProgram() wollte ich verhindern. Da kann man auch gleich alles mit einem Shell Script erschlagen.
Ich hab da in der Zwischenzeit auch ein bischen mit gdk_event_put() experimentiert. Aber das Event wird wohl nur an die eigenen Fenster gesendet: https://mail.gnome.org/archives/gtk-app ... 00226.html
Hab da auch den Hinweis auf Xlib gefunden und mal damit experimentiert. Allerdings hab ich es noch nicht soweit geschafft, dass irgendein Fenster irgendetwas macht (nichtmal meine eigenen), stattdessen crasht meine Test Anwendung immer mit einem Invalid Memory Access.
Ich hab da in der Zwischenzeit auch ein bischen mit gdk_event_put() experimentiert. Aber das Event wird wohl nur an die eigenen Fenster gesendet: https://mail.gnome.org/archives/gtk-app ... 00226.html
Hab da auch den Hinweis auf Xlib gefunden und mal damit experimentiert. Allerdings hab ich es noch nicht soweit geschafft, dass irgendein Fenster irgendetwas macht (nichtmal meine eigenen), stattdessen crasht meine Test Anwendung immer mit einem Invalid Memory Access.
- Programie
- Beiträge: 1280
- Registriert: 06.08.2005 22:56
- Computerausstattung: https://www.sysprofile.de/id160800
- Wohnort: Gernsbach
- Kontaktdaten:
Re: Tastatureingaben an aktives Fenster senden
So, habe es jetzt zumindest mal geschafft, dass mein Programm nicht mehr durch einen Invalid Memory Access crashed. Aber es funktioniert einfach nicht. Es kommen keine Tastatureingaben an (auch nicht in den StringGadgets von dem Programm selbst)...
Hier ist mein aktueller Stand:
Einiges davon habe ich mir aus dem Code vom xdotool zusammengebastelt.
Hier ist mein aktueller Stand:
Code: Alles auswählen
EnableExplicit
ImportC ""
gdk_screen_get_active_window(*screen)
gdk_screen_get_default()
gdk_x11_window_get_xid(*window)
EndImport
ImportC "-lX11"
XOpenDisplay(*display)
XSendEvent(display, xWindow, propagate, event_mask, event_send)
XStringToKeysym(string.p-utf8)
XFlush(display)
EndImport
Structure XKeyEvent
type.i ; KeyPress or KeyRelease
serial.l ; # of last request processed by server
send_event.i ; true if this came from a SendEvent request
*display ; Display the event was read from
window.i ; ''event'' window it is reported relative to
root.i ; root window that the event occurred on
subwindow.i ; child window
time.i ; milliseconds
x.i ; pointer x coordinate in event window
y.i ; pointer y coordinate in event window
x_root.i ; x coordinate relative to root
y_root.i ; y coordinate relative to root
state.i ; key or button mask
keycode.i ; detail
same_screen.i; same screen flag
EndStructure
Structure charcodemap
key.w
code.a
symbol.l
group.i
modmask.i
needs_binding.i
EndStructure
#KeyPressMask = 1
#KeyPress = 2
#KeyRelease = 3
Procedure SendKey(*display, *key.charcodemap, modstate)
Protected *gdkWindow = gdk_screen_get_active_window(gdk_screen_get_default())
Debug *gdkWindow
Protected xWindow = gdk_x11_window_get_xid(*gdkWindow)
Debug xWindow
Protected mask = modstate | *key\modmask
Protected keyEvent.XKeyEvent
keyEvent\display = *display
keyEvent\subwindow = 0
keyEvent\time = 0
keyEvent\same_screen = #True
keyEvent\window = xWindow
keyEvent\keycode = *key\code
keyEvent\state = mask | *key\group << 13
keyEvent\type = #KeyPress
XSendEvent(*display, keyEvent\window, #True, #KeyPressMask, keyEvent)
XFlush(*display)
Delay(100)
keyEvent\type = #KeyRelease
XSendEvent(*display, keyEvent\window, #True, #KeyPressMask, keyEvent)
XFlush(*display)
EndProcedure
Procedure SendKeyLoop(param)
Protected *display = XOpenDisplay(0)
Repeat
Protected symbol = XStringToKeysym("A")
Debug symbol
Protected key.charcodemap
key\code = 0
key\symbol = symbol
key\needs_binding = 1
SendKey(*display, key, 0)
Delay(1000)
ForEver
EndProcedure
If OpenWindow(0, 0, 0, 500, 130, "Test", #PB_Window_ScreenCentered)
StringGadget(0, 10, 10, 480, 30, "")
StringGadget(1, 10, 50, 480, 30, "")
StringGadget(2, 10, 90, 480, 30, "")
SetActiveGadget(0)
CreateThread(@SendKeyLoop(), 0)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
- Programie
- Beiträge: 1280
- Registriert: 06.08.2005 22:56
- Computerausstattung: https://www.sysprofile.de/id160800
- Wohnort: Gernsbach
- Kontaktdaten:
Re: Tastatureingaben an aktives Fenster senden
Habe es jetzt geschafft Tastatureingaben an das aktive Fenster zu senden.
Ganz einfach: mit XTestFakeKeyEvent (so macht es auch xdotool wenn das Zielfenster den Fokus hat)
Was mich an dem Code aktuell noch stoert: Der absolute Pfad zur libXtst.so.6. Wenn ich nur den Dateiname ohne Pfad beim Import angebe bekomme ich einen Linker Error (gcc: error: libXtst.so.6: No such file or directory).
Allerdings funktioniert es mit OpenLibrary ohne absoluten Pfad. Eventuell werde ich einfach die Funktion mit einem Prototype + GetFunction ansprechen.
Ganz einfach: mit XTestFakeKeyEvent (so macht es auch xdotool wenn das Zielfenster den Fokus hat)
Code: Alles auswählen
EnableExplicit
ImportC "-lX11"
XOpenDisplay(*display)
XStringToKeysym(string.p-utf8)
XKeysymToKeycode(*display, keysym)
XFlush(display)
EndImport
ImportC "/usr/lib/x86_64-linux-gnu/libXtst.so.6"
XTestFakeKeyEvent(display, keycode, is_press, delay)
EndImport
Procedure SendKeyLoop(param)
Protected *display = XOpenDisplay(0)
Repeat
Protected symbol = XStringToKeysym("A")
Protected code = XKeysymToKeycode(*display, symbol)
Debug symbol
Debug code
XTestFakeKeyEvent(*display, code, #True, 0)
XTestFakeKeyEvent(*display, code, #False, 0)
XFlush(*display)
Delay(1000)
ForEver
EndProcedure
If OpenWindow(0, 0, 0, 500, 130, "Test", #PB_Window_ScreenCentered)
StringGadget(0, 10, 10, 480, 30, "")
StringGadget(1, 10, 50, 480, 30, "")
StringGadget(2, 10, 90, 480, 30, "")
SetActiveGadget(0)
CreateThread(@SendKeyLoop(), 0)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Allerdings funktioniert es mit OpenLibrary ohne absoluten Pfad. Eventuell werde ich einfach die Funktion mit einem Prototype + GetFunction ansprechen.
Re: Tastatureingaben an aktives Fenster senden
@Programie
Klasse!
Nicht schlecht!
ImportC "-lXtst"
XTestFakeKeyEvent(display, keycode, is_press, delay)
EndImport
probiert ?
Klasse!
Nicht schlecht!
Ähm! Schon mal:Programie hat geschrieben:Was mich an dem Code aktuell noch stoert: Der absolute Pfad zur libXtst.so.6. Wenn ich nur den Dateiname ohne Pfad beim Import angebe bekomme ich einen Linker Error (gcc: error: libXtst.so.6: No such file or directory).
ImportC "-lXtst"
XTestFakeKeyEvent(display, keycode, is_press, delay)
EndImport
probiert ?
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
- Programie
- Beiträge: 1280
- Registriert: 06.08.2005 22:56
- Computerausstattung: https://www.sysprofile.de/id160800
- Wohnort: Gernsbach
- Kontaktdaten:
Re: Tastatureingaben an aktives Fenster senden
Ah... soweit hab ich nicht gedacht. Aber damit funktioniert es, danke!ccode_new hat geschrieben:Ähm! Schon mal:
ImportC "-lXtst"
XTestFakeKeyEvent(display, keycode, is_press, delay)
EndImport
probiert ?
Was genau macht denn das "-l" beim Import? Das andere mit "-lX11" hab ich auch nur im englischen Forum gefunden.
Re: Tastatureingaben an aktives Fenster senden
Das -l ist Präfix für lib.
Ist eine C-Linker-Anweisung für den gcc-Linker (ld).
Ist eine C-Linker-Anweisung für den gcc-Linker (ld).
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat