Sending keyboard events to other windows from wxwidget app in linux - linux

I'm writing a linux application using C++ and wxWidgets.
From my application, I need to send keyboard events to the window that currently has the focus (not belonging to my application!).
My questions are:
How can I find out what window has the focus?
How can I send a keyboard event to a window not belonging to my application?
Thanks
Daniele

XGetInputFocus(3).
X11 does not care about "applications". There are only windows. It's enough to have a window ID (Window is the Xlib data type). Use whatever method of sending events works. There are two methods I know of: XSendEvent(3) and XTestFakeKeyEvent(3). The former method does not work with some programs that chose to ignore events coming from XSendEvent. The latter one requires the XTest extension, which is present in most, but not all, modern servers.
Note that InputFocus is a valid window designator for XSendEvent, and XTestFakeKeyEvent is delivered to the window that has the focus anyway, so you probably don't need to call XGetInputFocus at all.

If you use 2.9, you can use wxUIActionSimulator. It is intended to work with other windows of the same (wxWidgets) application but AFAICS it should actually work with the windows of other applications when using X11 too (however I didn't test it myself).

Related

Running GTK in its own background thread

I have a set of old MFC DLLs that act as a frame buffer emulation. One of them contains processing for drawing commands then blits to an in-memory bitmap, the other DLL is the "main" DLL that controls Windowing and events by running a CWnd in its own Afx thread, and displays the in-memory bitmap.
The application that links against these basically has no idea they are there, they simply call "init" and "update" while running their app, expecting to see pixel data output on the Windows window instead of actual hardware.
Now I need to port this to Linux and looking at something like GTK, but during investigation it looks like GTK expects to be in control of the main loop and is event driven which is expected of a GUI toolkit, but many others also allow the user to manually pump the main loop instead of handing off control and only communicating with messaging.
Ideally, I'd want to just kick off GTK in its own thread and let it handle windowing and messaging alone, then blitting when "update" is called, while the user's main app is running as the critical main thread.
If we cant just plop GTK main_loop() into a seperate thread, I see that gtk_main_iteration may be used instead, but there are a lot of questions close to this one that users say that GTK shouldnt be used in this way, but the same could be said of our CWnd MFD implementation. At this point, there is no changing the mechanisms of how these DLLs work, the user's app must be the "main" and the processing/windowing must be transparent.
The other option is to just use X11, but I'd really like to have other widgets easily usable like toolbars, menuing, XShm extensions transparently used, resource management, etc.
Can this be done in GTK or is there better options?

does Xlib have any library call for Window associated process ID?

goal: is to collect information about user interactive program in Tracking app.
most efficient way is through process ID. the only way i can think of is getting Xlib Window associated process ID, does other ways around?
going through documentation, and source code, no clue for Window associated process ID attribute, maybe Xlib doesn't keep PID, or does it?
non efficient solution is through Window name attribute.
Xlib doesn't keep process ids - it was designed to work on a variety of OS'es with different process abstractions, and across networks, where a pid on one machine isn't very useful on another machine.
But since most X applications today are being run on Unix-like machines and displayed locally, not over the network, many modern toolkits adopted a convention of storing the process id in a property on the window of that application. See the _NET_WM_PID section of the Extended Window Manager Hints specification for details.
The X server doesn't have that information. In fact, there may not even be a PID available -- clients can connect to an X server over the network.
If all you need to do is identify what program is being used, though, you could look at the WM_CLASS window property. This property contains a pair of strings that are used to identify the window to the window manager, and usually includes the name of the application.

Add a "global" keystroke handler to Linux/X-Windows system

I would like to add a keystroke handler to my Linux system (actually Ubuntu Linux, but pointers to X11 generally will be helpful).
The goal is simple enough in principle, I have a "drawing" program that lets me write on a transparent panel. I want to have a single keystroke that toggles this from the top to the bottom (and back again) of the window stack.
I guess I need to interact with the window manager, but that's where my ideas run out. Any suggestions for research directions?
Thanks,
Toby

Intercept and send keystrokes with Python on Linux

I'm looking for a way to intercept all keyboard signals before they reach the active application. I then want to interpret and map the keystrokes before sending them on to the currently active application.
A Python library would be great, but C/C++ would also suffice.
I'm assuming you are using a system with X(org). If not some stuff can be done as well as the evdev level, but that's a another story.
Two parts in your question:
intercepting all key events -> XGrabKeyboard()
sending key events to the active application: I'd use libfakekey, it's a bit hacky hacky (it dynamically remaps part of the current keymap to send the KeySym you want to send) but it worked for me (small tip, don't forget to gerenate both the key presses and key release events :p).
Of course in your application grabbing the keyboard, you will have to listen to the KeyEvents from X and send keys from there.

drop/rewrite/generate keyboard events under Linux

I would like to hook into, intercept, and generate keyboard (make/break) events under Linux before they get delivered to any application. More precisely, I want to detect patterns in the key event stream and be able to discard/insert events into the stream depending on the detected patterns.
I've seen some related questions on SO, but:
either they only deal with how to get at the key events (key loggers etc.), and not how to manipulate the propagation of them (they only listen, but don't intercept/generate).
or they use passive/active grabs in X (read more on that below).
A Small DSL
I explain the problem below, but to make it a bit more compact and understandable, first a small DSL definition.
A_: for make (press) key A
A^: for break (release) key A
A^->[C_,C^,U_,U^]: on A^ send a make/break combo for C and then U further down the processing chain (and finally to the application). If there is no -> then there's nothing sent (but internal state might be modified to detect subsequent events).
$X: execute an arbitrary action. This can be sending some configurable key event sequence (maybe something like C-x C-s for emacs), or execute a function. If I can only send key events, that would be enough, as I can then further process these in a window manager depending on which application is active.
Problem Description
Ok, so with this notation, here are the patterns I want to detect and what events I want to pass on down the processing chain.
A_, A^->[A_,A^]: expl. see above, note that the send happens on A^.
A_, B_, A^->[A_,A^], B^->[B_,B^]: basically the same as 1. but overlapping events don't change the processing flow.
A_, B_, B^->[$X], A^: if there was a complete make/break of a key (B) while another key was held (A), X is executed (see above), and the break of A is discarded.
(it's in principle a simple statemachine implemented over key events, which can generate (multiple) key events as output).
Additional Notes
The solution has to work at typing speed.
Consumers of the modified key event stream run under X on Linux (consoles, browsers, editors, etc.).
Only keyboard events influence the processing (no mouse etc.)
Matching can happen on keysyms (a bit easier), or keycodes (a bit harder). With the latter, I will just have to read in the mapping to translate from code to keysym.
If possible, I'd prefer a solution that works with both USB keyboards as well as inside a virtual machine (could be a problem if working at the driver layer, other layers should be ok).
I'm pretty open about the implementation language.
Possible Solutions and Questions
So the basic question is how to implement this.
I have implemented a solution in a window manager using passive grabs (XGrabKey) and XSendEvent. Unfortunately passive grabs don't work in this case as they don't capture correctly B^ in the second pattern above. The reason is that the converted grab ends on A^ and is not continued to B^. A new grab is converted to capture B if still held but only after ~1 sec. Otherwise a plain B^ is sent to the application. This can be verified with xev.
I could convert my implementation to use an active grab (XGrabKeyboard), but I'm not sure about the effect on other applications if the window manager has an active grab on the keyboard all the time. X documentation refers to active grabs as being intrusive and designed for short term use. If someone has experience with this and there are no major drawbacks with longterm active grabs, then I'd consider this a solution.
I'm willing to look at other layers of key event processing besides window managers (which operate as X clients). Keyboard drivers or mappings are a possibility as long as I can solve the above problem with them. This also implies that the solution doesn't have to be a separate application. I'm perfectly fine to have a driver or kernel module do this for me. Be aware though that I have never done any kernel or driver programming, so I would appreciate some good resources.
Thanks for any pointers!
Use XInput2 to make device(keyboard) floating, then monitor KeyPress and KeyRelease event on the device, using XTest to regenerate KeyPress & KeyRelease event.

Resources