mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-04 08:55:35 +00:00
app: [macos] don't relay key events handled by the IME
Widgets such as Editor use certain key events such as the backspace key to implement text editing. On macOS, such key events are sometimes used by an input method, and in those cases the key effect would be applied twice: first by the IME and then the Editor. Report such key events through the doCommandBySelector callback, which receives key events not handled by the IME. References: https://todo.sr.ht/~eliasnaur/gio/616 Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+50
-4
@@ -15,6 +15,7 @@ __attribute__ ((visibility ("hidden"))) CALayer *gio_layerFactory(BOOL presentWi
|
||||
@end
|
||||
|
||||
@interface GioView : NSView <CALayerDelegate,NSTextInputClient>
|
||||
@property NSEvent *lastKeyDown;
|
||||
@property uintptr_t handle;
|
||||
@property BOOL presentWithTrans;
|
||||
@end
|
||||
@@ -132,7 +133,10 @@ static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFl
|
||||
handleMouse(self, event, MOUSE_SCROLL, dx, dy);
|
||||
}
|
||||
- (void)keyDown:(NSEvent *)event {
|
||||
// Stash the event for use by doCommandBySelector.
|
||||
self.lastKeyDown = event;
|
||||
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||
self.lastKeyDown = nil;
|
||||
NSString *keys = [event charactersIgnoringModifiers];
|
||||
gio_onKeys(self.handle, (__bridge CFTypeRef)keys, [event timestamp], [event modifierFlags], true);
|
||||
}
|
||||
@@ -143,9 +147,47 @@ static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFl
|
||||
- (void)insertText:(id)string {
|
||||
gio_onText(self.handle, (__bridge CFTypeRef)string);
|
||||
}
|
||||
- (void)doCommandBySelector:(SEL)sel {
|
||||
// Don't pass commands up the responder chain.
|
||||
// They will end up in a beep.
|
||||
- (void)doCommandBySelector:(SEL)action {
|
||||
NSEvent *event = self.lastKeyDown;
|
||||
if (event == nil) {
|
||||
return;
|
||||
}
|
||||
int key = 0;
|
||||
if (action == @selector(deleteBackward:)) {
|
||||
key = KEY_DELETE_BACKWARD;
|
||||
} else if (action == @selector(deleteForward:)) {
|
||||
key = NSDeleteFunctionKey;
|
||||
} else if (action == @selector(insertNewline:)) {
|
||||
NSString *keys = [event charactersIgnoringModifiers];
|
||||
if ([keys isEqualToString:@"\r"]) {
|
||||
key = KEY_RETURN;
|
||||
} else {
|
||||
key = KEY_ENTER;
|
||||
}
|
||||
} else if (action == @selector(moveUp:)) {
|
||||
key = NSUpArrowFunctionKey;
|
||||
} else if (action == @selector(moveDown:)) {
|
||||
key = NSDownArrowFunctionKey;
|
||||
} else if (action == @selector(moveLeft:)) {
|
||||
key = NSLeftArrowFunctionKey;
|
||||
} else if (action == @selector(moveRight:)) {
|
||||
key = NSRightArrowFunctionKey;
|
||||
} else if (action == @selector(cancelOperation:)) {
|
||||
key = KEY_ESCAPE;
|
||||
} else if (action == @selector(insertTab:)) {
|
||||
key = KEY_TAB;
|
||||
} else if (action == @selector(scrollToBeginningOfDocument:)) {
|
||||
key = NSHomeFunctionKey;
|
||||
} else if (action == @selector(scrollToEndOfDocument:)) {
|
||||
key = NSEndFunctionKey;
|
||||
} else if (action == @selector(scrollPageUp:)) {
|
||||
key = NSPageUpFunctionKey;
|
||||
} else if (action == @selector(scrollPageDown:)) {
|
||||
key = NSPageDownFunctionKey;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
gio_onCommandBySelector(self.handle, key, [event timestamp], [event modifierFlags]);
|
||||
}
|
||||
|
||||
- (BOOL)hasMarkedText {
|
||||
@@ -183,6 +225,10 @@ static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFl
|
||||
}
|
||||
- (void)insertText:(id)string
|
||||
replacementRange:(NSRange)replaceRange {
|
||||
NSEvent *event = self.lastKeyDown;
|
||||
if (event == nil) {
|
||||
return;
|
||||
}
|
||||
NSString *str;
|
||||
// string is either an NSAttributedString or an NSString.
|
||||
if ([string isKindOfClass:[NSAttributedString class]]) {
|
||||
@@ -190,7 +236,7 @@ static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFl
|
||||
} else {
|
||||
str = string;
|
||||
}
|
||||
gio_insertText(self.handle, (__bridge CFTypeRef)str, replaceRange);
|
||||
gio_insertText(self.handle, (__bridge CFTypeRef)str, replaceRange, [event timestamp], [event modifierFlags]);
|
||||
}
|
||||
- (NSUInteger)characterIndexForPoint:(NSPoint)p {
|
||||
return gio_characterIndexForPoint(self.handle, p);
|
||||
|
||||
Reference in New Issue
Block a user