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];
|
||||
|
||||
// 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
|
||||
_currentDeferredClient = nil;
|
||||
_currentCandidateClient = nil;
|
||||
|
@ -328,35 +335,46 @@ public:
|
|||
|
||||
- (void)setValue:(id)value forTag:(long)tag client:(id)sender
|
||||
{
|
||||
NSString *newInputMode;
|
||||
Formosa::Gramambular::FastLM *newLanguageModel;
|
||||
|
||||
if ([value isKindOfClass:[NSString class]] && [value isEqual:kPlainBopomofoModeIdentifier]) {
|
||||
_inputMode = kPlainBopomofoModeIdentifier;
|
||||
_languageModel = &gLanguageModelPlainBopomofo;
|
||||
newInputMode = kPlainBopomofoModeIdentifier;
|
||||
newLanguageModel = &gLanguageModelPlainBopomofo;
|
||||
}
|
||||
else {
|
||||
_inputMode = kBopomofoModeIdentifier;
|
||||
_languageModel = &gLanguageModel;
|
||||
newInputMode = kBopomofoModeIdentifier;
|
||||
newLanguageModel = &gLanguageModel;
|
||||
}
|
||||
|
||||
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
|
||||
if (!basisKeyboardLayoutID) {
|
||||
basisKeyboardLayoutID = @"com.apple.keylayout.US";
|
||||
}
|
||||
// Only apply the changes if the value is changed
|
||||
if (![_inputMode isEqualToString:newInputMode]) {
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
|
||||
[sender overrideKeyboardWithKeyboardNamed:basisKeyboardLayoutID];
|
||||
// Remember to override the keyboard layout again -- treat this as an activate eventy
|
||||
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
|
||||
if (!basisKeyboardLayoutID) {
|
||||
basisKeyboardLayoutID = @"com.apple.keylayout.US";
|
||||
}
|
||||
[sender overrideKeyboardWithKeyboardNamed:basisKeyboardLayoutID];
|
||||
|
||||
if (!_bpmfReadingBuffer->isEmpty()) {
|
||||
_bpmfReadingBuffer->clear();
|
||||
[self updateClientComposingBuffer:sender];
|
||||
}
|
||||
_inputMode = newInputMode;
|
||||
_languageModel = newLanguageModel;
|
||||
|
||||
if ([_composingBuffer length] > 0) {
|
||||
[self commitComposition:sender];
|
||||
}
|
||||
if (!_bpmfReadingBuffer->isEmpty()) {
|
||||
_bpmfReadingBuffer->clear();
|
||||
[self updateClientComposingBuffer:sender];
|
||||
}
|
||||
|
||||
if (_builder) {
|
||||
delete _builder;
|
||||
_builder = new BlockReadingBuilder(_languageModel);
|
||||
_builder->setJoinSeparator("-");
|
||||
if ([_composingBuffer length] > 0) {
|
||||
[self commitComposition:sender];
|
||||
}
|
||||
|
||||
if (_builder) {
|
||||
delete _builder;
|
||||
_builder = new BlockReadingBuilder(_languageModel);
|
||||
_builder->setJoinSeparator("-");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1110,24 +1128,30 @@ public:
|
|||
- (BOOL)handleEvent:(NSEvent *)event client:(id)client
|
||||
{
|
||||
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];
|
||||
if (!functionKeyKeyboardLayoutID) {
|
||||
functionKeyKeyboardLayoutID = @"com.apple.keylayout.US";
|
||||
}
|
||||
|
||||
[client overrideKeyboardWithKeyboardNamed:functionKeyKeyboardLayoutID];
|
||||
return NO;
|
||||
NSString *functionKeyKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kFunctionKeyKeyboardLayoutPreferenceKey];
|
||||
if (!functionKeyKeyboardLayoutID) {
|
||||
functionKeyKeyboardLayoutID = @"com.apple.keylayout.US";
|
||||
}
|
||||
|
||||
// reset when function key is released
|
||||
NSString *basisKeyboardLayoutID = [[NSUserDefaults standardUserDefaults] stringForKey:kBasisKeyboardLayoutPreferenceKey];
|
||||
if (!basisKeyboardLayoutID) {
|
||||
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];
|
||||
return NO;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue