• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: -charactersIgnoringModifiers and the shift key
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: -charactersIgnoringModifiers and the shift key


  • Subject: Re: -charactersIgnoringModifiers and the shift key
  • From: John Stiles <email@hidden>
  • Date: Thu, 17 Apr 2008 14:10:45 -0700

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 (email@hidden)

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:
This email sent to email@hidden
_______________________________________________

Cocoa-dev mailing list (email@hidden)

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:
This email sent to email@hidden


References: 
 >-charactersIgnoringModifiers and the shift key (From: John Stiles <email@hidden>)
 >Re: -charactersIgnoringModifiers and the shift key (From: Greg Titus <email@hidden>)
 >Re: -charactersIgnoringModifiers and the shift key (From: John Stiles <email@hidden>)
 >Re: -charactersIgnoringModifiers and the shift key (From: John Stiles <email@hidden>)
 >Re: -charactersIgnoringModifiers and the shift key (From: Ken Thomases <email@hidden>)
 >Re: -charactersIgnoringModifiers and the shift key (From: John Stiles <email@hidden>)

  • Prev by Date: Re: Determining which sheet closed with panels in separate nibs
  • Next by Date: Re: Determining which sheet closed with panels in separate nibs
  • Previous by thread: Re: -charactersIgnoringModifiers and the shift key
  • Next by thread: Re: -charactersIgnoringModifiers and the shift key
  • Index(es):
    • Date
    • Thread