winemac: Don't return characters for Ctrl-(non-letter symbol) keypresses from ToUnicodeEx() as X11 driver already does (try 2)
ken at codeweavers.com
Tue Sep 10 14:46:13 CDT 2013
On Sep 10, 2013, at 5:45 AM, Phil Krylov wrote:
> On Tue, Sep 10, 2013 at 6:05 AM, Ken Thomases <ken at codeweavers.com> wrote:
>> Is there a specific problem that you're trying to fix?
> Yes. I didn't file a bug report yet, but an application I am using
> (IBM Translation Manager) has some functionality bound to Ctrl-[0-9/]
> keypresses. Now with the Mac driver when I press Ctrl-1, for example,
> the function bound to Ctrl-1 is executed, but also '1' gets inserted
> into the active Richedit control which is wrong.
Are you able to test what happens with IBM Translation Manager on Windows with some of the layouts I mentioned?
>> The Mac driver's ToUnicodeEx() implementation started out very similar to the X11 driver's. It was basically a copy that I hacked on. It originally had this same restriction. However, some testing revealed that this is not an absolute restriction on Windows. For example, in the Khmer keyboard layout, Control-<digit> produces characters for some digits. Given that some Windows keyboard layouts produce characters for Control-<digit>, I figured it was best left up to the Mac keyboard layout.
>> Similarly for Control-<punctuation>. For example, the Windows Chinese keyboard layouts produce characters for some of those keystrokes. So does the Czech layout.
> Yes I investigated the Mac keyboard layout files and found out that
> the real problem is there - Ctrl-1 is really bound to produce '1' etc.
> But when I press Ctrl-1 e.g. in TextEdit nothing gets inserted and a
> "beep" is heard, but there is no simple way to understand what's
> happening due to TextEdit's closed-sourcedness. Thanks for the Khmer
> and Czech Windows layouts info.
I'm not sure what's happening in TextEdit, either. The source for TextEdit itself is actually available with the Xcode examples, but the problem is in Cocoa. The NSEvent gives "1", etc. for the -characters and -charactersIgnoringModifiers. The Control-<digit> special-case processing must happen within -[NSResponder -interpretKeyEvents:]. Indeed, in a test program, that calls back to -doCommandBySelector: with -noop: as the selector rather than calling -insertText: with a string.
That's not a result of the default Cocoa key binding in /System/Library/Frameworks/AppKit.framework/Versions/C/Resources/StandardKeyBinding.dict, which doesn't bind Control-<digit> at all.
For what it's worth, TextWrangler inserts digits for Control-<digit>.
Even so, perhaps Cocoa's refusal to insert text for Control-<digit> means it's OK to ignore that in the Mac driver.
Hmm. In poking around with keyboard layouts, I've found that the Lithuanian one makes it very difficult to type digits without a numeric keypad. One way is to use a dead key followed by one of the digit keys. The other way is to use Control-Option-<digit>. (Control-<digit> still doesn't do it, even though that would be very useful for this layout, which suggests the special handling in Cocoa is unconditional.)
>> If a modification like this were justified, it should go earlier in macdrv_ToUnicodeEx(). There's a section at the top where I moved the checks for combinations that don't produce characters.
>> Also, the check should test that Alt is _not_ pressed, since Control-Alt-<digit or punct> and Control-Alt-Shfit-<digit or punct> very commonly produce characters. Control-Alt is a synonym for the AltGr key on some keyboards (e.g. Swiss).
>> Finally, if we're going to pursue this, there are some minor style issues I'd prefer be changed. So, check with me before resubmitting.
> Ok, I'll retry, although after this answer of yours I have rather
> little hope left as I don't know any other apps affected by this
> behaviour, so it can't be called a 'broad' breakage.
After considering what Cocoa is doing, I've changed my mind at least with respect to Control-<digit>. I'd be willing to accept such a patch with the changes I described: put the check earlier in the function with the others; make sure Alt (VK_MENU) is not pressed; also make sure Option isn't pressed, which won't be reflected in lpKeyState but should be checked in thread_data->last_modifiers as is done when computing modifierKeyState.
The situation with Control-<punctuation> is less clear. I'm not sure what to do there. Cocoa doesn't seem to have as consistent special handling. With some keyboard layouts, for some punctuation characters, Control-<punctuation> does insert text. Therefore, some users may depend on that working in Wine.
As to my minor style quibbles:
* Don't refer to "Carbon" since it's not really accurate. That comment probably won't be necessary as such in the new location, which already has an introductory comment which uses "Mac keyboard layouts" in a similar sense.
* Use the form "Control-<category>" instead of "CTRL + <category>".
* When testing if a number falls within a range, I prefer that the comparands be ordered least to greatest, as on a number line. Put another way, inequality operators should always be of the less-than(-or-equal) kind. So: '0' <= virtKey && virtKey <= '9'
More information about the wine-devel