I have an NSView that calls interpretKeyEvents
for keyDown
events. For some keys like the letter 'a', pressing and holding the key results in repeated calls to insertText
. For other keys like 'x', insertText
is called once and that is it. I would like press and hold to always call insertText
. I'm guessing press and hold for these keys is interpreted as something else, but I cannot find it. I have implemented doCommandBySelector
as described by the documentation, but that is never called either.
Below is a minimal example program that demonstrates the behaviour.
// clang++ -framework AppKit -o proof-of-concept proof-of-concept.mm
#include <stdio.h>
#import <Cocoa/Cocoa.h>
@interface AppView : NSView<NSTextInputClient>
@end
@implementation AppView
- (void)keyDown:(NSEvent *)event {
printf("keydown\n");
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
}
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange {
printf("insertText\n");
}
- (BOOL)acceptsFirstResponder { return YES; }
- (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange {}
- (void)unmarkText {}
- (NSRange)selectedRange { return NSMakeRange(NSNotFound, 0); }
- (NSRange)markedRange { return NSMakeRange(NSNotFound, 0); }
- (BOOL)hasMarkedText { return NO; }
- (nullable NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range actualRange:(nullable NSRangePointer)actualRange { return nil; }
- (NSArray<NSAttributedStringKey> *)validAttributesForMarkedText { return [NSArray array]; }
- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(nullable NSRangePointer)actualRange { return NSMakeRect(0, 0, 0, 0); }
- (NSUInteger)characterIndexForPoint:(NSPoint)point { return 0; }
@end
int main(int argc, char **argv, char **envp, char **apple) {
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
NSRect windowDimensions = NSMakeRect(0, 0, 300, 300);
NSWindow *window = [[NSWindow alloc] initWithContentRect:windowDimensions
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskResizable
backing:NSBackingStoreBuffered
defer:NO];
AppView *windowView = [[AppView alloc] initWithFrame:windowDimensions];
[window setContentView:windowView];
[window makeKeyAndOrderFront:nil];
[NSApp run];
return 0;
}
Is there an explanation for why interpretKeyEvents
handles some key repeats by calling insertText
and ignores others?