Re: -charactersIgnoringModifiers and the shift key
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