Hotkey field in XUL for Firefox - firefox

I have a Firefox extension written in XUL. It takes a hotkey. I want to have an input field where the user can press any key and I can programmatically determine what key was pressed.
I don't care about key combos which have meta meanings inside the OS (I don't need to capture Ctrl + Alt + Del).
If the key is already defined by Firefox, I'm OK with not capturing it (for instance, if the user presses F1 and help pops up instead of the key being captured, I'm fine).
I would also love to have some way to determine programmatically whether the key pressed already has some other meaning inside of Firefox, but that is likely out of scope for this request. I just mention it in case it's easy.
My current solution, which seems to have been adopted by a number of add-ons, is to provide a text box where the user can type a printable character and then a series of check boxes for modifier keys. This solution is barely workable but terrible for a number of reasons (it doesn't allow users to use non-printing keys such as function keys in their combos, it allows the user to input invalid characters (such as Unicode characters with no physical key on the keyboard), and it's just awkward to use).
Thanks!

You can use Inline Options
https://developer.mozilla.org/en-US/Add-ons/Inline_Options
You can detect the key pressed in the text input and write your modifiers like accel or alt.
Source example:
http://git.io/vez1o

Related

User assigned key equivalents

I'm working on a Status Bar App. I'd like to allow the user to modify the menu item key equivalents to their own preferences. I've seen this done before it's a pretty common feature.
A prefs window usually has an area with textfields where the user enters their keyboard shortcut for specific menu items.
How does one setup the textfield so that it displays the modifier key fonts?
The default NSTextfield ignores modifiers.
Also I have yet to find an example project showing this functionality, if anyone has a link that would be very helpful.
You may wish to take a look at Shortcut Recorder which allows the user to record key equivalents using modifiers and then for you to retrieve them and set them for the NSMenuItem.
Once the user has recorder their shortcut/key combination you can access the SRRecorderControl's objectValue property which has values for the key code and modifier flags.
https://github.com/Kentzo/ShortcutRecorder
The modifier keys all have Unicode values that you can see in the "Special Characters" palette and they are displayed by the normal system font. Most of them are in the "Technical Symbols" category of the palette but the up-arrows for the Shift and Caps Lock keys are in the "Arrows" section.
You can insert these values when editing label elements in Interface Builder or Xcode, or include their corresponding Unicode values when creating something like an NSString object.
For example, the Shift key's UTF-8 sequence (as shown in the palette) is E2 87 A7 so one way to set it programmatically is to add those bytes to an array and create an NSString from the UTF-8 array. I prefer the array approach because it's "bulletproof"; it will always be interpreted as UTF-8 and do what you expect. If you try to insert characters directly into #"" or CFSTR() strings, you then have to make sure your source file's encoding is correct (and older versions of Xcode wouldn't even allow this, they'd assume ASCII only).

Getting "complete" and "menu-complete" to work together

I found out that the Bash shell supports a type of autocompletion that is different from the "traditional" autocompletion, where all possibilities get listed on the following line.
With the "traditional" autocompletion, if I type ch and then press the Tab key, I get something like:
$ ch
chacl chgrp chmod chown chvt
But if I add the following line to my /etc/inputrc (which remaps the Tab key to the built-in menu-complete function):
Tab: menu-complete
then the behavior of the shell changes: the word to be completed is replaced "inline" with a single match from the list of possible completions, and if I press the Tab key again, the word gets replaced with the next match.
I found this useful, but I still wanted to keep the traditional autocompletion and have it bound to the key combination Ctrl + Tab. So I added the following line to my /etc/inputrc file, according to what the readline library documentation suggests:
Ctrl-Tab: complete
However, adding this line only seems to make both Tab and Ctrl-Tab call the traditional complete function.
Does anyone know what I am doing wrong?
Thanks in advance!
To start with, I'm not a massive expert in this area, but I think I can answer your question. First of all, while you are using Bash, Bash is a shell which interprets keyboard commands that it receives from a terminal / console. While you are informing Bash how to react to specific key combinations in the inputrc file, your Terminal determines precisely which character is 'sent' to the Shell before the inputrc file even enters the equation.
Unfortunately, on my system (granted, it's OSX - but I don't think this is strange behaviour when compared to Linux), both Tab and Ctrl-Tab send the same keyboard input to the shell. Infact, both Tab and Ctrl-Tab send a Ctrl-I command to the shell, and indeed, if I enter Ctrl-I when using the terminal, it performs the completion as if I hit Tab.
The software (installed on most Linux systems by default), showkey will tell you what keys the shell is receiving when you press specific keyboard inputs as you push them.
Anyway, my suggestion to you is to use Shift-Tab, which does appear to send it's own key-code to the shell. Shift-Tab on my computer shows up (using showkey) as '<ESC>[Z', which I think is pretty standard across the board. As such, your inputrc file with the following bindings should allow you to use shift-tab instead of ctrl-tab to achieve what you desire:
Tab: menu-complete
"\e[Z": complete
The \e in the second binding represents the escape character, and the [Z are simply the characters as shown using showkey. You can get a similar effect on OSX by simply using cat, running cat from within a terminal and pressing Shift-Tab will show you "^[[Z", where ^[ represents the escape character and the other characters are as before.
I know this doesn't resolve your question precisely, but as I don't think you are able to use Ctrl-Tab as a key combination, without re-mapping Ctrl-Tab to another keybinding within your terminal (more likely to be easier if you are using a GUI terminal), this is likely as close as you can get without significant effort!
I have ShiftTab bound to menu-complete-backward, so it goes back one step if I skipped the right completion, and I've mapped Ctrlq to complete, so if there are several possible completions I hit Ctrlq to list them without having to cycle through them.
# Make Tab cycle between possible completions
# Cycle forward: Tab
# Cycle backward: Shift-Tab
TAB: menu-complete
"\e[Z": menu-complete-backward
# Make C-q display the list of possible completions
Control-q: complete
# Display the list of matches when no further completion is possible
set show-all-if-unmodified on
Edit: Ctrlq is bound to quoted-insert by default, that is, it tells the shell to take the next key literally. quoted-insert is also bound to Ctrlv, so you don't lose that functionality if you rebind Ctrlq. Anyway, I've found that AltESC also works, by default, for showing the possible completions (as far as I can tell it is equivalent to TAB); note that it may be seized by Gnome, then either double press ESC or rebind "Switch windows directly" in Settings → Devices → Keyboard → Navigation.
The following should achieve what you're looking for (if I understand correctly!)
In your .inputrc
# display all possible matches for an ambiguous pattern at first tab
set show-all-if-ambiguous on
# next tab(s) will cycle through matches
TAB: menu-complete
# shift tab cycles backward
"\e[Z": menu-complete-backward
Where to start, if you can or cant do this is dependent your keyboard and your drivers and there isn't one catch all answer. Each key press and release generates a sequenced key pair (key down and release) (scancode) these codes are then translated by the kernel into keycodes for example on my laptop keyboard 0x3a 0xba are translated to keycode 15 (down and up) these are then translated into actions such as return letter c a / you can assign actions to keysyms using the keycode/hex/binary/octal notation which codes match which letters is determined by the kernel translation table which is fairly standardized, however the first part signal that's translated to keycodes is different for most keyboards.
Continuing with the earlier example for me shift tab (and alt and control and any combination) produce keycode 15 however in hex it produces 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a 0x2a and this is because shift alt and control are special keys (modifiers) these multiply out against the keycodes and fill out the dumpkeys table the kernel is limited to the number of assignments as well this is determined by your choice of keymap and shares resources with your terminal colors (if your char set its defined above the threshold it limits your terminal color scope). And this all goes out the window if your in an xserver and has a whole new system. Most of these things can be changed,modified and manipulated by the user and programs installed. My point to all this is to emphasize that there is no catch all for the mapping of the tab key and its going to vary keyboard drivers to kbd drivers (now if you find a solution that happens to work for you excellent :)) but chances are it won't be portable and might not work if you change keyboards and might not translate between xserver and tui. What i recommend is learning the steps to modify your kbd on the go.
will give you the decimal octal hex notation for a key press on the same line
--full-table -1 >> keytable
will give you a documented with your full list of keycode->keysym pairing in a format that will give you a better picture of your layout and from there you can either use loadkey to change a keys value or ad an entry in .inputrc or your main rc file. You can also create a custom key.map file.
Further escape sequence translation is determined by the "$TERM" variable and each virtual terminal emulator can be different
infocmp "$TERM"
will give you a list of your terminal escape sequences
Resources:
https://man7.org/linux/man-pages/man4/console_codes.4.html
https://www.gnu.org/software/screen/manual/html_node/Input-Translation.html
http://kbd-project.org/docs/scancodes/scancodes.html
https://www.vt100.net/
So to sum up.
Your keyboard drivers
Your kemap choice
Your virtual terminal emulator
and your kernel
form the backbone of remapping dificult keys (tab/s-tab/a-tab)
I'm not sure Ctrl-Tab is a real character; my terminal, for instance, ignores the combination. I think the only way to use Ctrl-Tab is to use your terminal emulator to map it to some otherwise unused escape sequence, then bind that sequence to complete.

Remap Caps lock key to Esc in Mma 7

TLDR: How do I get CapsLock to translate to "ShortNameDelimiter" in Mma 7?
I like pretty text in my mma notebooks, and often define functions as f[\[Alpha]_] =... so as to match the exact equation that I'm working with. As such, it involves a lot of Esc-letter-Esc sequences, and reaching for Esc every other stroke breaks my flow of typing.
Now, the CapsLock key is seldom used (I can't remember the last time I needed it), but conveniently placed (your pinky is right there!). Remapping it to Esc on vim worked wonders for me and I was wondering if there was a way to do the same in mma, without having to modify the system's keyboard layout.
I tried editing KeyEventTranslations.tr by adding the following in EventTranslations[{...
Item[KeyEvent["CapsLock"], "ShortNameDelimiter"]
but that had no effect. Is there another way to do it? Is CapsLock not the correct identifier? If it helps, I'm using Mma7 student version on a Mac.
Modifier keys are handled quite specially, and I doubt Mathematica will be able to override the system. You probably have to do this in a layer between Mathematica and the OS. BUT, it is possible to make the key behave different depending on the application you are in. Thus with a bit of work, it MAY be possible to have the capslock key behave differently only in Mathematica.
edit: I did not see you say which operating system you had, so I've added Mac instructions.
Windows
For example, if you have Windows, you can use the program called http://www.autohotkey.com/ . It specifically has a feature where you can bind a key to a script, specifically the following script:
How can a hotkey or hotstring be made exclusive to certain program(s)?
In other words, I want a certain key to act as it normally does except when a specific window is active.
In the following example, NumpadEnter is made to perform normally except when a window titled "CAD Editor" is active. Note the use of the $ prefix in "$NumpadEnter", which is required to let the hotkey "send itself":
$NumpadEnter::
IfWinNotActive, CAD Editor
{
Send, {NumpadEnter}
return
}
; Otherwise, the desired application is active, so do a custom action:
Send, abc
return
This next example is more pure than the above, but it will only work if the "CAD Editor" application is designed to ignore the NumpadEnter key itself. The tilde prefix (~) makes NumpadEnter into a non-suppressed hotkey, meaning that the NumpadEnter keystroke itself is always sent to the active window, the only difference being that it triggers a hotkey action. The ~ feature requires Windows NT/2k/XP.
~NumpadEnter::
IfWinNotActive, CAD Editor
return
; Otherwise, the desired application is active, so do a custom action:
Send, abc
return
To quote from "MRCS" in this forum post, you may find the following useful:
The first one I named CapsLockR.ahk and contains the following script:
CapsLock UP::Run C:\Documents and Sett...[path to script]...\CapsLock.ahk
The second one is named CapsLock.ahk and has this script:
GetKeyState, state, CapsLock, T
if state = D
SetCapsLockState, off
else
SetCapsLockState, on
exit
Thus worse comes to worst, if you are having trouble modifying the "Behave like Foo if Active Window = Mathematica else behave like Bar" script, you can tack on this to manually toggle the CapsLock state I think. Googling will also reveal more results.
Linux
I know that on Linux, you can use the program called xbindkeys to bind the CapsLock to a script, from which you can in turn call xdo if you detect Mathematica is one of the topmost windows (e.g. via Getting pid and details for topmost window , or xdotool getwindowfocus) or worse-comes-to-worst, you can just have a script which toggles your configuration between CapsLock -> xdotool key Escape, xdotool type "whatever", xdotool key Escape ("Mathematica mode") and "normal mode"... though that may prevent you from YELLING AT MATHEMATICIANS OVER INSTANT MESSAGING WHILE DOING MATHEMATICS. Unless you You may need to find some way to programatically toggle CapsLock, perhaps by creating a dummy CapsLock key (though that's an extreme hack, it is likely one can find some kind of library; perhaps Anybody know how to toggle caps lock on/off in Python? may be useful). (This issue could be avoided by using a key besides CapsLock, or not caring that you want to keep your CapsLock functionality; you could also just turn another key you never use into CapsLock.)
Mac
Mac may have similar tools. For example, you can get xdotool like on Linux above via the MacPorts project. I hear the CapLock key cannot normally be rebound as easily on Mac, so if you can deal with another key it may be much easier. But theoretically it should be possible...
If you wish to use CapsLock, you can use PCKeyboardHack http://pqrs.org/macosx/keyremap4macbook/extra.html to remap the CapLock key to something which will tell OS X to let you remap the CapsLock. Then you remap it, then bind the key using Quicksilver to a script that makes calls xdotool to check if you're in Mathematica also also to issue the :esc:...:esc: if you are (see the Linux section of this answer). Otherwise you simulate a keypress on the CapsLock. But you remapped CapsLock! So you might need to make another dummy key you never use into the CapsLock key, and trigger a keypress on that using Cocoa libraries or a simple AppleScript. If you wish to pursue the CapsLock route, you might find Using Caps Lock as Esc in Mac OS X useful.

How to determine if a certain key is pressed, knowing only its position on U.S. keyboards?

Consider that, for a Windows video game, I need to determine if the key which generates the ` and ~ characters on the U.S. English keyboard layout (which is usually below the Escape key and left to 1) has been pressed. This may sound like a trivial question, but it doesn't seem like one to me.
When Windows sends keyboard messages, it specifies the virtual key code and the OEM scan code. We can't rely on the OEM scan code, because "the value depends on the OEM" - and nor can we depend on the virtual key code, because it depends on the currently active keyboard layout.
Our current "solution" is to use LoadKeyboardLayout and MapVirtualKeyEx to find the OEM scan code of the key that generates the ` character on the U.S. English keyboard layout, then just listen for that OEM scan code. The problem is that this doesn't work if the user doesn't have the U.S. English layout installed.
Is there a real way to do this on Windows?
The OEM scancode does not change from keyboard to keyboard. No reason not to use it.
Back in the DOS-days the same scancodes have been used for games because it has been the only way to detect key-up and key-down events. Noone had problems with it and I doubt it will change in the future.
If you want another option you may want to give DirectInput-API a try. It gives you the raw scancodes as well and if I'm not mistaken you can also query the physical position, dimension and whatnot of each key.
Tie the game action to the character, not the position of the key. Otherwise, how do you tell the user which key to press? "under the escape key"? They may not have anything there, but if you tell them "the ^ key", they can look for it.
You'll probably also want to make it configurable to accomodate exotic keyboard layouts and user preferences.

Using Numpad with Modifier Keys exhibits curious behavior

I have a keyboard event listener, and I am listening for the number pad key codes (1 through 9) for when number lock is activated; this works fine. However, in my app I also want to allow usage of a modifier key (CTRL) along with the number pad keys. The strange thing is that when holding CTRL, pressing 1 or 3 does not generate any keyboard event whatsoever, whereas 2 and 4 - 9 do generate the expected events. I have seen other references to this issue after some Googling, so I do not believe this is necessarily Flash-specific, but I have yet to find any answers.
I tried using SHIFT as a modifier, but that just results in generating the key codes from the number pad as if number lock was off (eg, SHIFT+Numpad1 returns the End keycode, regardless of number lock state) - apparently this is intentional Windows behavior. ALT is not an option with the numpad due to altcodes.
Any ideas on how to get CTRL+Numpad1 and CTRL+Numpad3 to generate the keyboard events? Or any explanation as to why they don't?
Edit: I tried out using these key combinations in Firefox as enriquein suggests below, and all the key combinations work A-OK, leading me to believe that this is likely a Flash-specific issue, or at least not a hardware issue.
I have run into issues in the past with numpad keys on specific keyboards. Various key combinations fail to register on specific keyboards, and it is possible that the keyboard you are using may just not be generating any event in that case. It's not guaranteed to work, but I would recommend trying out a different keyboard (different vendor, etc) and see if that works. It also might be an issue with localized keyboards, if you are using a non-english keyboard.
I'm almost certain it's not Flash related because I had similar problems with a localized keyboard and could not get it to generate events at all for certain keys or key combinations.
Try enumerating all key events and searching trough what they're mapped to, or google evtest.c, compile it and run it and see what it has to say.
Indeed it looks like its keyboard specific. I tried the key combinations as I read this question in Firefox and they triggered the same event as pressing Ctrl+Number (which is switch to tab #Number).
This was using a standard US/101-key english keyboard (no extra media buttons or anything).
Some keyboards don't register certain key combinations. I think that this is down to how they are put together. For example some may register left hand Ctrl + key combination but not right Ctrl + same key!
A work around would be to detect the key down and key up events for the Ctrl key.
You could then raise a custom event for Ctrl + numpad key or work with a volatile flag to show the Ctrl key state.

Resources