Fixes the bug on handling arrow keys.

This commit is contained in:
zonble 2022-01-28 01:35:15 +08:00
parent 2bbaa4a793
commit fc0c077193
3 changed files with 33 additions and 25 deletions

View File

@ -87,7 +87,7 @@ static inline NSString *LocalizationNotNeeded(NSString *s) {
+ (VTHorizontalCandidateController *)horizontalCandidateController; + (VTHorizontalCandidateController *)horizontalCandidateController;
+ (VTVerticalCandidateController *)verticalCandidateController; + (VTVerticalCandidateController *)verticalCandidateController;
+ (TooltipController *)tooltipController; + (TooltipController *)tooltipController;
- (void)_showTooltip:(NSString *)tooltip composingBuffer:(NSString *)composingBuffer client:(id)client; - (void)_showTooltip:(NSString *)tooltip composingBuffer:(NSString *)composingBuffer cursorIndex:(NSInteger)cursorIndex client:(id)client;
- (void)_hideTooltip; - (void)_hideTooltip;
@end @end
@ -246,8 +246,11 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
- (void)deactivateServer:(id)client - (void)deactivateServer:(id)client
{ {
InputStateDeactive *newState = [[InputStateDeactive alloc] init]; InputStateEmpty *empty = [[InputStateEmpty alloc] init];
[self handleState:newState client:client]; [self handleState:empty client:client];
InputStateDeactive *deactive = [[InputStateDeactive alloc] init];
[self handleState:deactive client:client];
} }
- (void)setValue:(id)value forTag:(long)tag client:(id)sender - (void)setValue:(id)value forTag:(long)tag client:(id)sender
@ -366,11 +369,13 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
// MARK: Handle Candidates // MARK: Handle Candidates
if ([state isKindOfClass:[InputStateChoosingCandidate class]]) { if ([state isKindOfClass:[InputStateChoosingCandidate class]]) {
NSLog(@"Handle Candidates");
return [self _handleCandidateState:(InputStateChoosingCandidate *) state input:input stateCallback:stateCallback candidateSelectionCallback:candidateSelectionCallback errorCallback:errorCallback]; return [self _handleCandidateState:(InputStateChoosingCandidate *) state input:input stateCallback:stateCallback candidateSelectionCallback:candidateSelectionCallback errorCallback:errorCallback];
} }
// MARK: Handle Marking // MARK: Handle Marking
if ([state isKindOfClass:[InputStateMarking class]]) { if ([state isKindOfClass:[InputStateMarking class]]) {
NSLog(@"Handle Marking");
if ([self _handleMarkingState:(InputStateMarking *)state input:input stateCallback:stateCallback candidateSelectionCallback:candidateSelectionCallback errorCallback:errorCallback]) { if ([self _handleMarkingState:(InputStateMarking *)state input:input stateCallback:stateCallback candidateSelectionCallback:candidateSelectionCallback errorCallback:errorCallback]) {
return YES; return YES;
} }
@ -637,6 +642,7 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
} }
InputStateInputting *currentState = (InputStateInputting *) state; InputStateInputting *currentState = (InputStateInputting *) state;
if (flags & NSEventModifierFlagShift) { if (flags & NSEventModifierFlagShift) {
// Shift + Right // Shift + Right
if (_builder->cursorIndex() < _builder->length()) { if (_builder->cursorIndex() < _builder->length()) {
@ -650,6 +656,8 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
} else { } else {
if (_builder->cursorIndex() < _builder->length()) { if (_builder->cursorIndex() < _builder->length()) {
_builder->setCursorIndex(_builder->cursorIndex() + 1); _builder->setCursorIndex(_builder->cursorIndex() + 1);
InputStateInputting *inputting = [self _buildInputtingState];
stateCallback(inputting);
} else { } else {
errorCallback(); errorCallback();
stateCallback(state); stateCallback(state);
@ -844,6 +852,7 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
index -= 1; index -= 1;
InputStateMarking *marking = [[InputStateMarking alloc] initWithComposingBuffer:state.composingBuffer cursorIndex:state.cursorIndex markerIndex:index]; InputStateMarking *marking = [[InputStateMarking alloc] initWithComposingBuffer:state.composingBuffer cursorIndex:state.cursorIndex markerIndex:index];
marking.readings = state.readings; marking.readings = state.readings;
NSLog(@"cursorBackwardKey %@", marking);
stateCallback(marking); stateCallback(marking);
} else { } else {
stateCallback(state); stateCallback(state);
@ -859,6 +868,7 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
index += 1; index += 1;
InputStateMarking *marking = [[InputStateMarking alloc] initWithComposingBuffer:state.composingBuffer cursorIndex:state.cursorIndex markerIndex:index]; InputStateMarking *marking = [[InputStateMarking alloc] initWithComposingBuffer:state.composingBuffer cursorIndex:state.cursorIndex markerIndex:index];
marking.readings = state.readings; marking.readings = state.readings;
NSLog(@"cursorForwardKey %@", marking);
stateCallback(marking); stateCallback(marking);
} else { } else {
stateCallback(state); stateCallback(state);
@ -1302,7 +1312,7 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
- (void)handleState:(InputState *)newState client:(id)client - (void)handleState:(InputState *)newState client:(id)client
{ {
NSLog(@"current state: %@ new state: %@", _state, newState ); NSLog(@"current state: %@ new state: %@", _state, newState );
if ([newState isKindOfClass:[InputStateDeactive class]]) { if ([newState isKindOfClass:[InputStateDeactive class]]) {
[self _handleInputStateDeactive:(InputStateDeactive *) newState previous:_state client:client]; [self _handleInputStateDeactive:(InputStateDeactive *) newState previous:_state client:client];
} }
@ -1326,7 +1336,6 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
if ([newState isKindOfClass:[InputStateChoosingCandidate class]]) { if ([newState isKindOfClass:[InputStateChoosingCandidate class]]) {
[self _handleInputStateChoosingCandidate:(InputStateChoosingCandidate *)newState previous:_state client:client]; [self _handleInputStateChoosingCandidate:(InputStateChoosingCandidate *)newState previous:_state client:client];
} }
_state = newState; _state = newState;
} }
@ -1405,26 +1414,31 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
[client setMarkedText:attrString selectionRange:NSMakeRange(cursorIndex, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)]; [client setMarkedText:attrString selectionRange:NSMakeRange(cursorIndex, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
gCurrentCandidateController.visible = NO; gCurrentCandidateController.visible = NO;
[self _showTooltip:state.tooltip composingBuffer:state.composingBuffer client:client]; [self _showTooltip:state.tooltip composingBuffer:state.composingBuffer cursorIndex:state.cursorIndex client:client];
} }
- (void)_handleInputStateChoosingCandidate:(InputStateChoosingCandidate *)state previous:(InputState *)previous client:(id)client - (void)_handleInputStateChoosingCandidate:(InputStateChoosingCandidate *)state previous:(InputState *)previous client:(id)client
{ {
NSUInteger cursorIndex = [state cursorIndex]; NSUInteger cursorIndex = [state cursorIndex];
NSAttributedString *attrString = [state attributedString]; NSAttributedString *attrString = [state attributedString];
NSLog(@"_handleInputStateChoosingCandidate 1");
NSLog(@"isMainThread :%d", [NSThread isMainThread]);
// the selection range is where the cursor is, with the length being 0 and replacement range NSNotFound, // the selection range is where the cursor is, with the length being 0 and replacement range NSNotFound,
// i.e. the client app needs to take care of where to put ths composing buffer // i.e. the client app needs to take care of where to put ths composing buffer
[client setMarkedText:attrString selectionRange:NSMakeRange(cursorIndex, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)]; [client setMarkedText:attrString selectionRange:NSMakeRange(cursorIndex, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
NSLog(@"_handleInputStateChoosingCandidate 2");
if (_inputMode == kPlainBopomofoModeIdentifier && [state.candidates count] == 1) { if (_inputMode == kPlainBopomofoModeIdentifier && [state.candidates count] == 1) {
NSString *buffer = [self _convertToSimplifiedChineseIfRequired:state.candidates.firstObject]; NSString *buffer = [self _convertToSimplifiedChineseIfRequired:state.candidates.firstObject];
[client insertText:buffer replacementRange:NSMakeRange(NSNotFound, NSNotFound)]; [client insertText:buffer replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
InputStateEmpty *empty = [[InputStateEmpty alloc] init]; InputStateEmpty *empty = [[InputStateEmpty alloc] init];
[self handleState:empty client:client]; [self handleState:empty client:client];
return; NSLog(@"_handleInputStateChoosingCandidate 31");
} else { } else {
if (![_state isKindOfClass:[InputStateChoosingCandidate class]]) { NSLog(@"_handleInputStateChoosingCandidate 32");
if (![previous isKindOfClass:[InputStateChoosingCandidate class]]) {
NSLog(@"_handleInputStateChoosingCandidate 33");
[self _showCandidateWindowWithState:state client:client]; [self _showCandidateWindowWithState:state client:client];
} }
} }
@ -1475,17 +1489,12 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
// update the composing text, set the client // update the composing text, set the client
NSInteger cursor = 0; NSInteger cursor = 0;
// NSInteger cursor = _latestReadingCursor;
if ([state respondsToSelector:@selector(cursorIndex)]) {
cursor = [[state performSelector:@selector(cursorIndex)] integerValue];
}
NSAttributedString *attrString = [state attributedString]; NSAttributedString *attrString = [state attributedString];
[client setMarkedText:attrString selectionRange:NSMakeRange(cursor, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)]; [client setMarkedText:attrString selectionRange:NSMakeRange(cursor, 0) replacementRange:NSMakeRange(NSNotFound, NSNotFound)];
_currentCandidateClient = client; _currentCandidateClient = client;
NSRect lineHeightRect = NSMakeRect(0.0, 0.0, 16.0, 16.0); NSRect lineHeightRect = NSMakeRect(0.0, 0.0, 16.0, 16.0);
cursor = state.cursorIndex;
if (cursor == [state.composingBuffer length] && cursor != 0) { if (cursor == [state.composingBuffer length] && cursor != 0) {
cursor--; cursor--;
} }
@ -1498,6 +1507,8 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
NSLog(@"lineHeightRectangle %@", exception); NSLog(@"lineHeightRectangle %@", exception);
} }
NSLog(@"lineHeightRectangle %@", NSStringFromRect(lineHeightRect));
if (useVerticalMode) { if (useVerticalMode) {
[gCurrentCandidateController setWindowTopLeftPoint:NSMakePoint(lineHeightRect.origin.x + lineHeightRect.size.width + 4.0, lineHeightRect.origin.y - 4.0) bottomOutOfScreenAdjustmentHeight:lineHeightRect.size.height + 4.0]; [gCurrentCandidateController setWindowTopLeftPoint:NSMakePoint(lineHeightRect.origin.x + lineHeightRect.size.width + 4.0, lineHeightRect.origin.y - 4.0) bottomOutOfScreenAdjustmentHeight:lineHeightRect.size.height + 4.0];
} else { } else {
@ -1711,15 +1722,11 @@ static double FindHighestScore(const vector<NodeAnchor> &nodes, double epsilon)
return instance; return instance;
} }
- (void)_showTooltip:(NSString *)tooltip composingBuffer:(NSString *)composingBuffer client:(id)client - (void)_showTooltip:(NSString *)tooltip composingBuffer:(NSString *)composingBuffer cursorIndex:(NSInteger)cursorIndex client:(id)client
{ {
NSRect lineHeightRect = NSMakeRect(0.0, 0.0, 16.0, 16.0); NSRect lineHeightRect = NSMakeRect(0.0, 0.0, 16.0, 16.0);
NSInteger cursor = 0; NSInteger cursor = cursorIndex;
if ([_state respondsToSelector:@selector(cursorIndex)]) {
cursor = [[_state performSelector:@selector(cursorIndex)] integerValue];
}
if (cursor == [composingBuffer length] && cursor != 0) { if (cursor == [composingBuffer length] && cursor != 0) {
cursor--; cursor--;
} }

View File

@ -70,7 +70,6 @@ class InputStateInputting: InputStateNotEmpty {
private let kMinMarkRangeLength = 2 private let kMinMarkRangeLength = 2
private let kMaxMarkRangeLength = 6 private let kMaxMarkRangeLength = 6
/// Represents that the user is marking a range in the composing buffer. /// Represents that the user is marking a range in the composing buffer.
class InputStateMarking: InputStateNotEmpty { class InputStateMarking: InputStateNotEmpty {
@objc private(set) var markerIndex: UInt = 0 @objc private(set) var markerIndex: UInt = 0
@ -108,19 +107,21 @@ class InputStateMarking: InputStateNotEmpty {
@objc var attributedString: NSAttributedString { @objc var attributedString: NSAttributedString {
let attributedSting = NSMutableAttributedString(string: composingBuffer) let attributedSting = NSMutableAttributedString(string: composingBuffer)
let end = markedRange.location + markedRange.length
attributedSting.setAttributes([ attributedSting.setAttributes([
.underlineStyle: NSUnderlineStyle.single.rawValue, .underlineStyle: NSUnderlineStyle.single.rawValue,
.markedClauseSegment: 0 .markedClauseSegment: 0
], range: NSRange(location: 0, length: markedRange.location)) ], range: NSRange(location: 0, length: markedRange.location))
attributedSting.setAttributes([ attributedSting.setAttributes([
.underlineStyle: NSUnderlineStyle.single.rawValue, .underlineStyle: NSUnderlineStyle.thick.rawValue,
.markedClauseSegment: 1 .markedClauseSegment: 1
], range: markedRange) ], range: markedRange)
attributedSting.setAttributes([ attributedSting.setAttributes([
.underlineStyle: NSUnderlineStyle.single.rawValue, .underlineStyle: NSUnderlineStyle.single.rawValue,
.markedClauseSegment: 2 .markedClauseSegment: 2
], range: NSRange(location: markedRange.location + markedRange.length, ], range: NSRange(location: end,
length: composingBuffer.count - (markedRange.location + markedRange.length) )) length: composingBuffer.count - end))
return attributedSting return attributedSting
} }

View File

@ -51,7 +51,7 @@ import Cocoa
self.charCode = charCode self.charCode = charCode
self.emacsKey = EmacsKeyHelper.detect(charCode: charCode, flags: event.modifierFlags) self.emacsKey = EmacsKeyHelper.detect(charCode: charCode, flags: event.modifierFlags)
self.cursorForwardKey = useVerticalMode ? .up : .left self.cursorForwardKey = useVerticalMode ? .down : .right
self.cursorBackwardKey = useVerticalMode ? .up : .left self.cursorBackwardKey = useVerticalMode ? .up : .left
self.extraChooseCandidateKey = useVerticalMode ? .left : .down self.extraChooseCandidateKey = useVerticalMode ? .left : .down
self.absorbedArrowKey = useVerticalMode ? .right : .up self.absorbedArrowKey = useVerticalMode ? .right : .up