diff --git a/app/os_macos.go b/app/os_macos.go index 4f43f7e18..13d595dd1 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -217,6 +217,13 @@ static void invalidateCharacterCoordinates(CFTypeRef viewRef) { } } } + +static void setFocus(CFTypeRef windowRef, CFTypeRef viewRef) { + NSWindow *window = (__bridge NSWindow *)windowRef; + NSView *view = (__bridge NSView *)viewRef; + [window makeFirstResponder:view]; +} + */ import "C" @@ -246,8 +253,9 @@ type window struct { cursor pointer.Cursor pointerBtns pointer.Buttons - scale float32 - config Config + scale float32 + config Config + focused bool } // viewMap is the mapping from Cocoa NSViews to Go windows. @@ -524,6 +532,9 @@ func gio_onMouse(view, evt C.CFTypeRef, cdir C.int, cbtn C.NSInteger, x, y, dx, typ = pointer.Release w.pointerBtns &^= btn case C.MOUSE_DOWN: + if !w.focused { + C.setFocus(w.window, w.view) + } typ = pointer.Press w.pointerBtns |= btn act, ok := w.w.ActionAt(pos) @@ -563,6 +574,16 @@ func gio_onFocus(view C.CFTypeRef, focus C.int) { w.SetCursor(w.cursor) } +//export gio_onResponder +func gio_onResponder(view C.CFTypeRef, first C.int) { + // That function is called when some child view becomes first responder. + w := mustView(view) + w.focused = first == 1 + if w.w.d != nil { + w.w.Event(key.FocusEvent{Focus: w.focused}) + } +} + //export gio_onChangeScreen func gio_onChangeScreen(view C.CFTypeRef, did uint64) { w := mustView(view) diff --git a/app/os_macos.m b/app/os_macos.m index b94a568d5..dfb0284af 100644 --- a/app/os_macos.m +++ b/app/os_macos.m @@ -185,6 +185,14 @@ - (NSRect)firstRectForCharacterRange:(NSRange)rng r = [self convertRect:r toView:nil]; return [[self window] convertRectToScreen:r]; } +- (BOOL) becomeFirstResponder { + gio_onResponder((__bridge CFTypeRef)self, 1); + return [super becomeFirstResponder]; +} +- (BOOL) resignFirstResponder { + gio_onResponder((__bridge CFTypeRef)self, 0); + return [super resignFirstResponder]; +} @end // Delegates are weakly referenced from their peers. Nothing