Skip to content
Snippets Groups Projects
Commit 44fa77a2 authored by George Nachman's avatar George Nachman
Browse files

If DefaultKeyBindings.dict leads you down a garden path to a multi-keystroke...

If DefaultKeyBindings.dict leads you down a garden path to a multi-keystroke combo that doesn't exist, revisit the keydown events seen along the way and replay them. Issue 3710.
parent 4ece1f64
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -1399,11 +1399,24 @@ static const int kDragThreshold = 3;
// Hide the cursor
[NSCursor setHiddenUntilMouseMoves:YES];
 
if ([_keyBindingEmulator handlesEvent:event]) {
NSMutableArray *eventsToHandle = [NSMutableArray array];
if ([_keyBindingEmulator handlesEvent:event extraEvents:eventsToHandle]) {
DLog(@"iTermNSKeyBindingEmulator reports that event is handled, sending to interpretKeyEvents.");
[self interpretKeyEvents:@[ event ]];
return;
}
[eventsToHandle addObject:event];
for (NSEvent *event in eventsToHandle) {
[self handleKeyDownEvent:event];
}
}
- (void)handleKeyDownEvent:(NSEvent *)event {
id delegate = [self delegate];
unsigned int modflag = [event modifierFlags];
unsigned short keyCode = [event keyCode];
BOOL rightAltPressed = (modflag & NSRightAlternateKeyMask) == NSRightAlternateKeyMask;
BOOL leftAltPressed = (modflag & NSAlternateKeyMask) == NSAlternateKeyMask && !rightAltPressed;
 
// Should we process the event immediately in the delegate?
if (!_hadMarkedTextBeforeHandlingKeypressEvent &&
Loading
Loading
Loading
Loading
@@ -10,7 +10,10 @@
 
@interface iTermNSKeyBindingEmulator : NSObject
 
// Returns YES if the user's key bindings should handle this event.
- (BOOL)handlesEvent:(NSEvent *)event;
// Indicates if the event should be handled by Cocoa's regular text processing path because it has
// a key binding. If this returns NO, then |extraEvents| may be filled in with additional events
// to process first. That happens when a series of keys is entered which make up a multi-key binding
// ending in an unhandleable binding.
- (BOOL)handlesEvent:(NSEvent *)event extraEvents:(NSMutableArray *)extraEvents;
 
@end
Loading
Loading
@@ -41,7 +41,9 @@ static struct {
{ '@', NSCommandKeyMask }
};
 
@implementation iTermNSKeyBindingEmulator
@implementation iTermNSKeyBindingEmulator {
NSMutableArray *_savedEvents;
}
 
+ (void)initialize {
if (self == [iTermNSKeyBindingEmulator self]) {
Loading
Loading
@@ -266,19 +268,22 @@ static struct {
- (instancetype)init {
self = [super init];
if (self) {
_savedEvents = [[NSMutableArray alloc] init];
_currentDict = [gRootKeyBindingsDictionary retain];
}
return self;
}
 
- (void)dealloc {
[_savedEvents release];
[_currentDict release];
[super dealloc];
}
 
- (BOOL)handlesEvent:(NSEvent *)event {
- (BOOL)handlesEvent:(NSEvent *)event extraEvents:(NSMutableArray *)extraEvents {
if (!gRootKeyBindingsDictionary) {
DLog(@"Short-circuit DefaultKeyBindings handling because no bindings are defined");
[_savedEvents removeAllObjects];
return NO;
}
DLog(@"Checking if default key bindings should handle %@", event);
Loading
Loading
@@ -288,6 +293,7 @@ static struct {
DLog(@"Couldn't normalize event to key!");
NSLog(@"WARNING: Unexpected charactersIgnoringModifiers=%@ in event %@",
event.charactersIgnoringModifiers, event);
[_savedEvents removeAllObjects];
return NO;
}
NSObject *obj = nil;
Loading
Loading
@@ -305,6 +311,7 @@ static struct {
// This is part of a multi-keystroke binding. Move down the tree.
self.currentDict = (NSDictionary *)obj;
DLog(@"Entered multi-keystroke binding with key: %@", selectedKey);
[_savedEvents addObject:event];
return YES;
}
 
Loading
Loading
@@ -313,11 +320,18 @@ static struct {
DLog(@"Default key binding is %@", obj);
if (![obj isKindOfClass:[NSArray class]]) {
[extraEvents addObjectsFromArray:_savedEvents];
[_savedEvents removeAllObjects];
return NO;
}
NSArray *theArray = (NSArray *)obj;
return ([theArray[0] isEqualToString:@"insertText:"]);
BOOL result = ([theArray[0] isEqualToString:@"insertText:"]);
if (!result) {
[extraEvents addObjectsFromArray:_savedEvents];
}
[_savedEvents removeAllObjects];
return result;
}
 
#pragma mark - Private
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment