Converting NSString to keyCode+modifiers for AXUIElementPostKeyboardEvent - cocoa

Edit: Turns out, I was misled during my initial explorations of the accessibility APIs. Once I found the secure text field in the AX hierarchy, I was easily able to set the value. Not sure what to do with this question beyond that, but I wanted to update this for future searchers.
I'm working on some code that will post keyboard events to targeted applications using the Accessibility APIs. So far, I have been able to write a trivial app that allows me to type in a string value and then post keyboard events with those key codes to the targeted application. In reality, the strings would be read from another location.
What I have not yet been able to figure out is how to ascertain whether and which modifier keys should also be posted. For instance, when I type Hello, world! into my test application, the input is sent to the other application as hello, world1 because I am not yet including the modifier keys to create the upper case H and the exclamation point. This is made doubly complicated by multi-keystroke characters like é or ü. Sending é sends a raw e with no accent for example.
Is there a simple method I am overlooking for discerning the modifiers to combine with a keycode for creating a particular NSString or unichar? If not, does anyone have a suggestion of how to proceed? So far, the best I have come up with is calling UCKeyTranslate with all possible modifier combinations until I find one that matches the unichar I get using -[NSString characterAtIndex:] I'm not sure this is scalable or reliable, though, given the multi-keystroke nature of some characters as noted above.
Thanks in advance!

This probably won't help. But just in case: Is it really necessary to send keyboard events? Because that is going to get really difficult if you need to support, say, Kotoeri.
It's a simple matter to override insertText: and doCommandBySelector: and send the results of the key sequence, rather than the individual keystrokes.

I have found a example which does the trick but it's incomplete:It will not be a general solution in any case ...how can this handle multiple keyboard layouts ?
There is an cgquartz obsolete function to do so: CGPostKeyboardEvent (not sure it's possible to pass only the char?) may be can still be used (marked undocumented with some side effect to but .. ).
EDIT: UCKeyTranslate as a way to build a dictionary. Interesting but how the OS do this? A better answer should be hidden somewhere !

Related

Best practice for key values in translation files

In general, translation methods take a key > value mapping and use the key to transform that into a value. Now I recognize two different methods to name your translation keys and within my team we do not come to consensus what seems to be the best method.
Method 1:
Use full English words or sentences:
Name => Name
Please enter your email address => Please enter your email address
Method 2:
Use keywords describing the situation:
NAME => Name
ENTER_EMAIL => Please enter your email address
I personally prefer method #1 because it directly shows the meaning of the message. If the translation is not present, you could fall back to the key and this doesn't cause any problems. However, the method is cumbersome when a translation changes frequently, because all the files need to be updated. Also for longer texts these keys become very large. This is solved by using keys like ENTER_EMAIL, but the phrasing is completely out of the context. The list of abstract translation keys would be huge, you need meta data for all the keys explaining their usage and collisions can occur much easier.
Is there a best of both worlds or a third method? How do you use translation keys in your application? In our case it is a php-based webapplication, but I think above problem is generic enough to talk about i18n in general.
This is a question that is also faced by iOS/OSX developers. And for them there is even a standard tool called genstrings which assumes method 1. But of course Apple developers don't have to use this tool--I don't.
While the safety net that you get with method 1 is nice (i.e you can display the key if you somehow forgot to localize a string) it has the downside that it can lead to conflicting keys. Sometimes one identical piece of display text needs to be localized in two different ways, due to grammar rules or differences in context. For instance the French translation for "E-mail" would be "E-mail" if it's a dialog title and "Envoyer un e-mail" if it's a button (in French the word "E-mail" is only a noun and can't be used as a verb, unlike in English where it's both a noun and a verb). With method 2 you could have keys EMAIL_TITLE and EMAIL_BUTTON to solve this issue, and as a bonus this would give a hint to translators to help them translate correctly.
One more advantage of method 2 is that you can change the English text without having to worry about updating the key in English and in all your localizations.
So I recommend method 2!
Why not use both worlds? I use method #1 for short strings, and method #2 for long strings that are full sentences. I am not afraid to mix both in the same file.
For example, in the following string the text may change if in a new app version the user experience is modified:
"screen description" = "Tap the plus button to add a new item. Tap an item for more options or to edit its details.";
So here it makes sense to apply method #2.
However, for simple strings like in the following example, method #1 is more useful:
"Preferences" = "Preferences";
In general when people try to standardize things it often appears restrictive to me. Personally, I prefer a more "anarchistic" approach where several methods are valid (not only as in this method #1 vs method #2 thread, but also for example when a team of developers fight over coding style).

Localizing spreadsheet cell names

I'm working on an application that has a spreadsheet-like interface. There is a grid of cells. Rows are numbered, and letters are used for the columns. So "names" like A2 and Q17 refer to cells in the grid.
I know I can use GetLocaleInfo(Ex) with LOCALE_SNATIVEDIGITS to get the appropriate digits for the user's locale, so I can format the row numbers. But I don't see something comparable for the locale-appropriate "alphabet".
I could imagine the same question arising for things like word processors that have an outline mode and need to be able to enumerate some list items with letters.
I've been pouring through the Windows NLS APIs, and I don't see anything like LOCALE_SNATIVEALPHABET nor do I see an API like EnumLocaleAlphabet. Am I missing such an API or am I stuck rolling my own?
Personally I haven't heard of such API. The closest to what you are asking would be ICU uchar's UBlockCode but it still won't give you concrete alphabet.
By the way, I don't think it is actually localize cell names unless you localize the whole User Interface. But in such case you may simply ask translators to provide valid cell symbols.
And this probably what you should do, because some writing systems do not have concept of alphabet at all. That is, it is called script, not alphabet. For example, I don't think it would be good idea to use Arabic for cell symbol (which glyph variant in such case?) nor I would use Chinese (all possible ideograms?).
My suggestion is: leave it to translators, if they want to localize it, that is OK, if they don't, just trust them, they really should know their craft.

Why do people use plain english as translation placeholders?

This may be a stupid question, but here goes.
I've seen several projects using some translation library (e.g. gettext) working with plain english placeholders. So for example:
_("Please enter your name");
instead of abstract placeholders (which has always been my instinctive preference)
_("error_please_enter_name");
I have seen various recommendations on SO to work with the former method, but I don't understand why. What I don't get is what do you do if you need to change the english wording? Because if the actual text is used as the key for all existing translations, you would have to edit all the translations, too, and change each key. Or don't you?
Isn't that awfully cumbersome? Why is this the industry standard?
It's definitely not proper normalization to do it this way. Are there massive advantages to this method that I'm not seeing?
Yes, you have to alter the existing translation files, and that is a good thing.
If you change the English wording, the translations probably need to change, too. Even if they don't, you need someone who speaks the other language to check.
You prep a new version, and part of the QA process is checking the translations. If the English wording changed and nobody checked the translation, it'll stick out like a sore thumb and it'll get fixed.
The main language is already existent: you don't need to translate it.
Translators have better context with a real sentence than vague placeholders.
The placeholders are just the keys, it's still possible to change the original language by creating a translation for it. Because when the translation doesn't exists, it uses the placeholder as the translated text.
We've been using abstract placeholders for a while and it was pretty annoying having to write everything twice when creating a new function. When English is the placeholder, you just write the code in English, you have meaningful output from the start and don't have to think about naming placeholders.
So my reason would be less work for the developers.
I like your second approach. When translating texts you always have the problem of homonyms. Like 'open' can mean a state of a window but also the verb to perform the action. In other languages these homonyms may not exist. That's why you should be able to add meaning to your placeholders. Best approach is to put this meaning in your text library. If this is not possible on the platform the framework you use, it might be a good idea to define a 'development language'. This language will add meaning to the text entries like: 'action_open' and 'state_open'. you will off course have to put extra effort i translating this language to plain english (or the language you develop for). I have put this philosophy in some large projects and in the long run this saves some time (and headaches).
The best way in my opinion is keeping meaning separate so if you develop your own translation library or the one you use supports it you can do something like this:
_(i18n("Please enter your name", "error_please_enter_name"));
Where:
i18n(text, meaning)
Interesting question. I assume the main reason is that you don't have to care about translation or localization files during development as the main language is in the code itself.
Well it probably is just that it's easier to read, and so easier to translate. I'm of the opinion that your way is best for scalability, but it does just require that extra bit of effort, which some developers might not consider worth it... and for some projects, it probably isn't.
There's a fallback hierarchy, from most specific locale to the unlocalised version in the source code.
So French in France might have the following fallback route:
fr_FR
fr
Unlocalised. Source code.
As a result, having proper English sentences in the source code ensures that if a particular translation is not provided for in step (1) or (2), you will at least get a proper understandable sentence than random programmer garbage like “error_file_not_found”.
Plus, what do you do if it is a format string: “Sorry but the %s does not exist” ? Worse still: “Written %s entries to %s, total size: %d” ?
Quite old question but one additional reason I haven't seen in the answers yet:
You could end up with more placeholders than necessary, thus more work for translators and possible inconsistent translations. However, good editors like Poedit or Gtranslator can probably help with that.
To stick with your example:
The text "Please enter your name" could appear in a different context in a different template (that the developer is most likely not aware of and shouldn't need to be). E.g. it could be used not as an error but as a prompt like a placeholder of an input field.
If you use
_("Please enter your name");
it would be reusable, the developer can be unaware of the already existing key for an error message and would just use the same text intuitively.
However, if you used
_("error_please_enter_name");
in a previous template, developers wouldn't necessarily be aware of it and would make up a second key (most likely according to a predefined wording scheme to not end up in complete chaos), e.g.
_("prompt_please_enter_name");
which then has to be translated again.
So I think that doesn't scale very well. A pre-agreed wording scheme of suffixes/prefixes e.g. for contexts can never be as precise as the text itself I think (either too verbose or too general, beforehand you don't know and afterwards it's difficult to change) and is more work for the developer that's not worth it IMHO.
Does anybody agree/disagree?

SSpeechRecognizer delegate to be called for any word spoke

I read about NSSpeechRecognizer and found that it can recognize a set of commands beings associated with it in delegate: -speechRecognizer:didRecognizeCommand:
I have a simple question: can this delegate be called for any word spoken by user?? as I think.. only a finite number of words can be associated with it!
Thanks,
Miraaj
It's exactly what it says on the tin: It's for recognizing commands. So, yes, you need to tell it up front what commands it should recognize.
It's not a dictation API. I would guess that if you tried to load up the command list with an English dictionary, you'd make recognition very processor-intensive, slow, and inaccurate.
If you want dictation, you should file an enhancement request to ask for it.

How do I access (listen for) the multimedia keys (play/pause) in Mac OS X?

I want to write a Songbird extension binds the multimedia keys available on all Apple Mac OS X platforms. Unfortunately this isn't an easy google search and I can't find any docs.
Can anyone point me resources on accessing these keys or tell me how to do it?
I have extensive programming experience, but this will be my first time coding in both MacOSX and XUL (Firefox, etc), so any tips on either are welcome.
Please note that these are not regular key events. I assume it must be a different type of system event that I will need to hook or subscribe to.
This blog post has a solution:
http://www.rogueamoeba.com/utm/posts/Article/mediaKeys-2007-09-29-17-00.html
You basically need to subclass NSApplication and override sendEvent,
looking for special scan codes. I don't know what songbird is, but if it's
not a real application then I doubt you'll be able to do this.
Or maybe you can, a simple category may suffice:
#implementation NSApplication(WantMediaKeysCategoryKBye)
- (void)sendEvent: (NSEvent*)event
{
// intercept media keys here
}
#end
Are you sure your multimedia keys are working in your installation? Every single key generates a scan code which is translated into a key code by the kernel. If xev doesn't show you any keycodes I guess those scan codes aren't mapped and so the kernel has no knowledge of them.
http://gentoo-wiki.com/HOWTO_Use_Multimedia_Keys has a nice explanation of finding key codes and offers help on how you can find raw scan codes and translate them into key codes.
xev might help you if you want to find out which codes are being sent by multimedia keys.

Resources