I'm using the npm module xterm on a mobile device. I've implemented my own "readline" by registering a callback with xterm.onData and then writing characters and moving the cursor accordingly.
On a mobile, typing foo and then backspace provides data fo to the callback.
However, detecting backspace via data === currentInput.slice(0, -1) doesn't always work, e.g. if we type ggg, the final g will be interpreted as a backspace.
So how can I know the backspace key was really pressed?
Related
For an automated test application I have to simulate large amount of unicode keyboard input into an old X11 application (of which I don't have any source access).
My program takes the input from an UCS-2 LE encoded input stream via stdin and the basic operation is as follows:
Save current keyboard layout and lock modifiers (XDisplayKeycodes, XGetKeyboardMapping, XkbGetState)
Unlock active modifiers (XkbLockModifiers)
Disable all X11 slave keyboard devices via Xinput2 extension
Read input into a key press queue until n unique symbols are encountered, where n is the number of possible keycodes as returned by XDisplayKeycodes.
Map these n unique X11 KeySyms via XChangeKeyboardMapping on the n available KeyCodes
Type the correct KeyCodes for all enqueued KeySyms via XTestFakeKeyEvent
Clear the queue and continue at 4.) until no input is available
Reactivate keyboards and restore initial modifiers and mappings
Basically this system works better and much more performant than any virtual X11 key input tool I've seen so far.
However, there is an issue I can currently only fix using ugly delays:
As any other X11 application, the target application receives a MappingNotify (request==Keyboard) event from the X server after my application succeeded in changing the keyboard mapping table.
The usual response of a X11 client is to call XRefreshKeyboardMapping to update Xlib's knowledge of the new keyboard layout.
Now if the the client has some lag processing its X11 event queue, the XRefreshKeyboardMapping call might return a too recent mapping that is already some generations too far in the future.
E.g. my input generator has already done the fourth XChangeKeyboardMapping when the target application just arrived at handling the second MappingNotify event in its XEvent queue handler.
Actually it should get the second generation of the map, which isn't available at the X server anymore at that time.
Unfortunately there is no map id or version of any kind in the keyboard MappingNotify event so that XRefreshKeyboardMapping could refer to a specific map ... and the X server does not seem to keep a history either.
The result is that the X11 application's KeyCode to KeySym conversion operates with an invalid layout and generates wrong KeySyms.
So basically I have to wait until all clients (or at least the one with the input focus) have requested and received my last XChangeKeyboardMapping map before I am allowed to do the next XChangeKeyboardMapping.
I can fix 99.9% of the errors using a delay before XChangeKeyboardMapping and that delay is calculated by some ugly witchcraft (amount of key strokes etc.) and is way to high if 100% accuracy has to be achieved.
So my question is if there is any way to programmatically be notified or to check if a X11 client has completed XRefreshKeyboardMapping or if its map is in sync with the server map?
If not, is there a way to get another X11 client's current mapping via xlib (to check if the map is current)?
Thanks for any hints!
I've done something similar on Windows in the past. I had the luxury of being able to use the SendInput function which accepts a KEYBDINPUT structure with KEYEVENTF_UNICODE flag. Unfortunately X11 does not support direct keystroke synthesizing of Unicode characters.
Since I cannot comment yet I'm forced to give a suggestion as answer:
Have you considered using the clipboard instead in order to transfer your "unicode input" into this X11 application's input field ?
You also might consider using direct Unicode input if that application uses a toolkit that supports this:
E.g. programs based on GTK+ (that includes all GNOME applications) support Unicode input.
Hold Ctrl + Shift and type u followed by the Unicode hex digits and release Ctrl and Shift again.
I guess it should be easy to synthesize these sequences using the Xtest extension.
I'm currently writing up my own ASCII Game Engine in bare metal on the Raspberry Pi 3.
I'd like to create a keyboard interface that will work like my planned NES controller over GPIO. This way I can swap what input I'm using or have multiplayer support.
My question is, is it possible (maybe using VT100 or the like) to query from putty a string of the keys being pressed at any given time? My plan is to pull the state of any button being pressed (ie no interrupts).
How can I ask for or constantly receive the keys being pressed? I'm assuming putty wont send me the keys pressed in this scenario: A + B + Left Arrow.
Thanks :)
Is there a way to detect if the mouse has been moved ANYWHERE on the X Server or a keyboard event occured? I need to react on the user doing anything with the X11 input devices.
I only managed to detect events on my own window using GTK.
I am thankful for every information (it does not have to be full code, an entry point would be good enough!)
Yes, you can do this using the Xinput2 extension. A complete, but rather small, tool which does this for cursor events can be found here (unclutter-xfixes). As a disclaimer, I am the author of that tool.
Another good resource in tutorial form can be found here.
Using XInput2 has multiple benefits:
No need to constantly poll the position (resource efficient)
Does not interfere with / break applications like selecting mouse events on all windows would.
What you don't get easily using Xinput2 is the exact position (but you can query it when you need it), but my understanding is that you don't need it anyway.
Once you loaded the extension, which I won't show here, you can select all events like this:
XIEventMask masks[1];
unsigned char mask[(XI_LASTEVENT + 7)/8];
memset(mask, 0, sizeof(mask));
XISetMask(mask, XI_RawMotion);
XISetMask(mask, XI_RawButtonPress);
XISetMask(mask, XI_RawKeyPress);
masks[0].deviceid = XIAllMasterDevices;
masks[0].mask_len = sizeof(mask);
masks[0].mask = mask;
XISelectEvents(display, DefaultRootWindow(display), masks, 1);
XFlush(display);
In your event queue, you can now look for the corresponding events.
For modern X11 implementations, xinput --test-xi2 --root will display great detail about all X11 input events available on your root window. I use this in a shell script that needs to wait on any input event:
echo "DEBUG $(date) waiting on X event"
xinput --test-xi2 --root | head -n 15 >/dev/null
echo "DEBUG $(date) got X event"
I'm trying to make an application like Launchy/Enso/etc., which pops up when the user presses the Caps Lock key.
To do this, I have needed to install a low-level keyboard hook (WH_KEYBOARD_LL), from which I subsequently spawn a thread to display the dialog to present to the user.
The trouble is, when I somehow steal focus (e.g. by clicking on another window) and subsequently press Caps Lock with a short delay, my window doesn't get the keyboard input: the input goes to the background window, even though my window is "active" (from looking at the title bar).
Of course, this gets pretty annoying, since I then end up typing something like "visu" (for "Visual Studio") inside a text processor (or a chat box...) and pressing Enter, withotu realizing that it didn't do what I intended.
(Funny thing is, after a 3-second (or so) pause, my window's title bar suddenly becomes "inactive", even though it was never active in the first place!)
How can I bypass this "protection" mechanism to actually activate my window?
Okay, I finally figured out a hack. (Microsoft employers: please look away...)
I intercept Caps Lock with a low-level keyboard hook, then when I detect VK_CAPITAL, I call
keybd_event(
VK_OEM_8,
(BYTE)MapVirtualKey(pKBDLLHook->vkCode, MAPVK_VK_TO_VSC),
(wParam == WM_KEYUP || wParam == WM_SYSKEYUP) ? KEYEVENTF_KEYUP : 0,
0
);
from within the handler.
Essentially, I just change the request to VK_OEM_8.
However, Notice that the virtual-key code does not correspond to the scan code. This is intentional -- VK_OEM_8 doesn't have a scan code (as far as I could tell, anyway) so I didn't have much of an option.
Then I just program based on VK_OEM_8 instead -- which is easy to intercept/handle/etc.
Hope this helps out other people.
I'm using Xlib for a project, and I'm trying to get the KeySym relative to a pressed key.
I've got the KeyCode relative to the pressed key, keyboard modifiers and keyboard indicators. I'm referring to this page to understand how to retrieve the correct key, but it must be out of date or something, because my X doesn't behave like that page says.
I've got some questions:
What is MODE SWITCH? How can I see what key is my MODE SWITCH and how can I set it? (via Xlib functions or via a command, it's the same).
That page says that the first 4 KeySyms associated to a KeyCode (found with XGetKeyboardMapping, or shown by xmodmap -pk command) are divided into two groups. MODE SWITCH switches between groups, and within a group the first or the second KeySym is chosen according to modifiers (ie, shift key) or indicators (ie, caps lock). But on my X I can see that if shift is pressed, I switch to the third KeySym, not the second one.
On many european layouts AltGr key is bound to KeySym XS_ISO_Level3_Shift, which doesn't belong to any keyboard modifier (ie, shift, lock, control, mod1, mod2, mod3, mod4 and mod5). When such XS_ISO_Level3_Shift is pressed, the fifth KeySym associated to the KeyCode is chosen. Why? Where can I found some info about this XS_ISO_Level3_Shift and about other keysyms that are actually used, but not documented on Xlib manuals?
It looks like the page you're reading predates Xkb - I'd guess that content is 10-15 years old at least.
See: http://www.xfree86.org/current/XKBproto.pdf
"xmodmap -pm" will show you the modifier keys such as mode switch.
With Xkb, the behavior of basically everything is configurable, I believe. Start looking at /usr/share/X11/xkb/ for example. I don't know a lot about it but hopefully looking at Xkb instead of old docs will get you pointed in the right direction.
Tronche's manual is incomplete. I found more info about keyboard functions in:
1. xlib.pdf
2. xlib html manual at static.cray-cyber.org. This doc is hidden and a bit broken. Links are typed in lowercase, but the actual documents are in uppercase. After correcting the urls in browser it's readable.
PDF is complete I guess. I don't know if [2] is complete too, but for example the chapter 16.2 (sorry, I can't give a link cause my link limit is exceeded) is far longer than in Tronche's doc.
I'm a beginner in understanding xlib, that's what I managed to google out today.