Here's what I ended up with. It's really not pretty but I think it should handle everything. I derived this from code on Carbon-dev (see "iGetKeys sample code problems in Tiger") so I think it's only fair to give back :) BTW, word to the wise, the Carbon-dev code looks like it has an endian bug, so be careful :) If anyone here spots a problem with the implementation, please let me know—it seems to be working but I might have missed yet another edge case. Wouldn't surprise me that much. :) For any curious Apple engineers reading along, I've now filed an enhancement request for this functionality in the OS. rdar://5871653 [NSEvent] Need -charactersIgnoringModifiersIncludingShift

@implementation NSEvent (OsGuiUtilsAdditions)

- (NSString*) charactersIgnoringModifiersIncludingShift {
// First, try -charactersIgnoringModifiers and look for keys which UCKeyTranslate translates
   // differently than AppKit.
   NSString* c = [self charactersIgnoringModifiers];
   if ([c length] == 1) {
       unichar codepoint = [c characterAtIndex:0];
if ((codepoint >= 0xF700 && codepoint <= 0xF8FF) || codepoint == 0x7F) {
           return c;
       }
   }
// OK, this is not a "special" key, so ask UCKeyTranslate to give us the character with no // modifiers attached. Actually, that's not quite accurate--we attach the Command modifier. // Command hints the OS to use Latin characters where possible, which is generally what we
   // are after here.
   OSStatus                 err;
   KeyboardLayoutRef        theCurrentLayout;
   const UCKeyboardLayout * uchrData;
   NSString*                result = @"";
err = KLGetCurrentKeyboardLayout(&theCurrentLayout);
   if (err != noErr)
       return @"";
err = KLGetKeyboardLayoutProperty(theCurrentLayout, kKLuchrData, (const void **)&uchrData);
   if (err == noErr && uchrData != NULL) {
       // Use UCKeyTranslate.
       UniChar buf[256];
       UniCharCount actualStringLength;
       UInt32 deadKeyState = 0;
err = UCKeyTranslate(
           uchrData,
           [self keyCode],
           kUCKeyActionDown,
cmdKey >> 8, // forcing the Command key to "on" hints the OS to show Latin characters where possible
           LMGetKbdType(),
           kUCKeyTranslateNoDeadKeysMask,
           &deadKeyState,
           lengthof(buf),
           &actualStringLength,
           buf
       );
if (err != noErr)
           return @"";

result = [NSString stringWithCharacters:buf length:actualStringLength];
   }
   else {
       UInt32 chars;
       UInt32 deadKeyState = 0;
       TextEncoding keyboardEncoding;
       const void *kchrData;
err = KLGetKeyboardLayoutProperty(theCurrentLayout, kKLKCHRData, &kchrData);
       if (err != noErr || kchrData == NULL)
           return @"";
chars = KeyTranslate(
           kchrData,
([self keyCode] & 0x7F) | cmdKey, // forcing the Command key to "on" hints the OS to show Latin characters where possible
           &deadKeyState);

       err = UpgradeScriptInfoToTextEncoding(
           (ScriptCode)GetScriptManagerVariable(smKeyScript),
           kTextLanguageDontCare,
           kTextRegionDontCare,
           0, // no font name
           &keyboardEncoding
       );

       if (err != noErr)
           return @"";
// There shouldn't be more than one character if dead key state was zero.
       // Accented characters take a single byte in legacy encodings.
       UInt8  singleChar = chars & 0xFF;
       result = [[[NSString alloc] initWithBytes:&singleChar
                                          length:1
encoding:CFStringConvertEncodingToNSStringEncoding(keyboardEncoding)] autorelease];
   }
return result;
}

@end




John Stiles wrote:
Hmm, OK. I guess there's no harm in leaving in the KCHR handling code. I was hoping to simplify things (this routine is already big and yucky) but I guess that's just not in the cards. Nothing about this whole hotkey ordeal has been simple!


Ken Thomases wrote:
On Apr 17, 2008, at 11:38 AM, John Stiles wrote:
Quick question: in Leopard, are there any keyboards left which don't have a uchr?

I found some sample code which includes a fallback case for if no 'uchr' resource is found (it uses plain KeyTranslate in this case) and I'm wondering whether this is still relevant in the Leopard-and-above timeframe.

All of the keyboard layouts that Apple ships provide uchr data. However, there's nothing stopping users from installing and using third-party keyboard layouts which don't. Many of those will be users who originally installed the non-uchr keyboard layout in Tiger and then upgraded to Leopard; the layout just comes along for the ride.

This is not a hypothetical. It has been a problem we've seen with our product.

Cheers,
Ken

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/jstiles%40blizzard.com

This email sent to [EMAIL PROTECTED]
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to