Override keyboard layout correctly. Fixes #86.
Using numerous NSLog's led to the discovery that when McBopofomo lost function (as described in #86), -setValue:forTag:client: was often called not just on the context of the foreground app, but also on the contexts of the background apps. This led to the theory that calling keyboard layout override in that method (not a documented way of doing things anyways) might corrupt the input method context. That we swapped out language model and the builder when the method got called didn't help. In this commit, we put back the keyboard layout override code to where it belongs -- in -activateServer: -- and we now only swap the language model and re-create the builder if the input method really changes (e.g. from Bopomofo to Plain Bopomofo, or vice versa). Similar defensive coding is also used in the function key handler in the -handleEvent:client: method.
This commit is contained in:
parent
3640c9f55f
commit
5f19be59b4
|
@ -251,6 +251,13 @@ public:
|
||||||
{
|
{
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
|
|
||||||
|
// Override the keyboard layout. Use US if not set.
|
||||||
|
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
|
||||||
|
if (!basisKeyboardLayoutID) {
|
||||||
|
basisKeyboardLayoutID = @"com.apple.keylayout.US";
|
||||||
|
}
|
||||||
|
[client overrideKeyboardWithKeyboardNamed:basisKeyboardLayoutID];
|
||||||
|
|
||||||
// reset the state
|
// reset the state
|
||||||
_currentDeferredClient = nil;
|
_currentDeferredClient = nil;
|
||||||
_currentCandidateClient = nil;
|
_currentCandidateClient = nil;
|
||||||
|
@ -328,22 +335,32 @@ public:
|
||||||
|
|
||||||
- (void)setValue:(id)value forTag:(long)tag client:(id)sender
|
- (void)setValue:(id)value forTag:(long)tag client:(id)sender
|
||||||
{
|
{
|
||||||
|
NSString *newInputMode;
|
||||||
|
Formosa::Gramambular::FastLM *newLanguageModel;
|
||||||
|
|
||||||
if ([value isKindOfClass:[NSString class]] && [value isEqual:kPlainBopomofoModeIdentifier]) {
|
if ([value isKindOfClass:[NSString class]] && [value isEqual:kPlainBopomofoModeIdentifier]) {
|
||||||
_inputMode = kPlainBopomofoModeIdentifier;
|
newInputMode = kPlainBopomofoModeIdentifier;
|
||||||
_languageModel = &gLanguageModelPlainBopomofo;
|
newLanguageModel = &gLanguageModelPlainBopomofo;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_inputMode = kBopomofoModeIdentifier;
|
newInputMode = kBopomofoModeIdentifier;
|
||||||
_languageModel = &gLanguageModel;
|
newLanguageModel = &gLanguageModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only apply the changes if the value is changed
|
||||||
|
if (![_inputMode isEqualToString:newInputMode]) {
|
||||||
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
|
|
||||||
|
// Remember to override the keyboard layout again -- treat this as an activate eventy
|
||||||
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
|
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
|
||||||
if (!basisKeyboardLayoutID) {
|
if (!basisKeyboardLayoutID) {
|
||||||
basisKeyboardLayoutID = @"com.apple.keylayout.US";
|
basisKeyboardLayoutID = @"com.apple.keylayout.US";
|
||||||
}
|
}
|
||||||
|
|
||||||
[sender overrideKeyboardWithKeyboardNamed:basisKeyboardLayoutID];
|
[sender overrideKeyboardWithKeyboardNamed:basisKeyboardLayoutID];
|
||||||
|
|
||||||
|
_inputMode = newInputMode;
|
||||||
|
_languageModel = newLanguageModel;
|
||||||
|
|
||||||
if (!_bpmfReadingBuffer->isEmpty()) {
|
if (!_bpmfReadingBuffer->isEmpty()) {
|
||||||
_bpmfReadingBuffer->clear();
|
_bpmfReadingBuffer->clear();
|
||||||
[self updateClientComposingBuffer:sender];
|
[self updateClientComposingBuffer:sender];
|
||||||
|
@ -358,6 +375,7 @@ public:
|
||||||
_builder = new BlockReadingBuilder(_languageModel);
|
_builder = new BlockReadingBuilder(_languageModel);
|
||||||
_builder->setJoinSeparator("-");
|
_builder->setJoinSeparator("-");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - IMKServerInput protocol methods
|
#pragma mark - IMKServerInput protocol methods
|
||||||
|
@ -1110,24 +1128,30 @@ public:
|
||||||
- (BOOL)handleEvent:(NSEvent *)event client:(id)client
|
- (BOOL)handleEvent:(NSEvent *)event client:(id)client
|
||||||
{
|
{
|
||||||
if ([event type] == NSFlagsChanged) {
|
if ([event type] == NSFlagsChanged) {
|
||||||
// function key pressed
|
|
||||||
BOOL includeShift = [[NSUserDefaults standardUserDefaults] boolForKey:kFunctionKeyKeyboardLayoutOverrideIncludeShiftKey];
|
|
||||||
if (([event modifierFlags] & ~NSShiftKeyMask) || (([event modifierFlags] & NSShiftKeyMask) && includeShift)) {
|
|
||||||
NSString *functionKeyKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kFunctionKeyKeyboardLayoutPreferenceKey];
|
NSString *functionKeyKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kFunctionKeyKeyboardLayoutPreferenceKey];
|
||||||
if (!functionKeyKeyboardLayoutID) {
|
if (!functionKeyKeyboardLayoutID) {
|
||||||
functionKeyKeyboardLayoutID = @"com.apple.keylayout.US";
|
functionKeyKeyboardLayoutID = @"com.apple.keylayout.US";
|
||||||
}
|
}
|
||||||
|
|
||||||
[client overrideKeyboardWithKeyboardNamed:functionKeyKeyboardLayoutID];
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset when function key is released
|
|
||||||
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
|
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
|
||||||
if (!basisKeyboardLayoutID) {
|
if (!basisKeyboardLayoutID) {
|
||||||
basisKeyboardLayoutID = @"com.apple.keylayout.US";
|
basisKeyboardLayoutID = @"com.apple.keylayout.US";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no override is needed, just return NO.
|
||||||
|
if ([functionKeyKeyboardLayoutID isEqualToString:basisKeyboardLayoutID]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function key pressed.
|
||||||
|
BOOL includeShift = [[NSUserDefaults standardUserDefaults] boolForKey:kFunctionKeyKeyboardLayoutOverrideIncludeShiftKey];
|
||||||
|
if (([event modifierFlags] & ~NSShiftKeyMask) || (([event modifierFlags] & NSShiftKeyMask) && includeShift)) {
|
||||||
|
// Override the keyboard layout and let the OS do its thing
|
||||||
|
[client overrideKeyboardWithKeyboardNamed:functionKeyKeyboardLayoutID];
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Revert back to the basis layout when the function key is released
|
||||||
[client overrideKeyboardWithKeyboardNamed:basisKeyboardLayoutID];
|
[client overrideKeyboardWithKeyboardNamed:basisKeyboardLayoutID];
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue