diff --git a/app/os_macos.go b/app/os_macos.go index 1da5083fd..73a063e6c 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -297,6 +297,11 @@ static void invalidateCharacterCoordinates(CFTypeRef viewRef) { } } } + +static void setFocus(CFTypeRef viewRef) { + NSView *view = (__bridge NSView *)viewRef; + [view.window makeFirstResponder:view]; +} */ import "C" @@ -514,7 +519,11 @@ func (w *window) EditorStateChanged(old, new editorState) { } } -func (w *window) ShowTextInput(show bool) {} +func (w *window) ShowTextInput(show bool) { + if show && !w.config.Focused { + C.setFocus(w.view) + } +} func (w *window) SetInputHint(_ key.InputHint) {} diff --git a/app/os_macos.m b/app/os_macos.m index 0a3f62629..01b42978b 100644 --- a/app/os_macos.m +++ b/app/os_macos.m @@ -47,13 +47,17 @@ - (void)windowDidChangeScreen:(NSNotification *)notification { } - (void)windowDidBecomeKey:(NSNotification *)notification { NSWindow *window = (NSWindow *)[notification object]; - GioView *view = (GioView *)window.contentView; - gio_onFocus(view.handle, 1); + GioView *view = (GioView *)window.contentView; + if ([window firstResponder] == view) { + gio_onFocus(view.handle, 1); + } } - (void)windowDidResignKey:(NSNotification *)notification { NSWindow *window = (NSWindow *)[notification object]; - GioView *view = (GioView *)window.contentView; - gio_onFocus(view.handle, 0); + GioView *view = (GioView *)window.contentView; + if ([window firstResponder] == view) { + gio_onFocus(view.handle, 0); + } } @end @@ -205,6 +209,14 @@ - (void)applicationDidHide:(NSNotification *)notification { - (void)dealloc { gio_onDestroy(self.handle); } +- (BOOL) becomeFirstResponder { + gio_onFocus(self.handle, 1); + return [super becomeFirstResponder]; + } +- (BOOL) resignFirstResponder { + gio_onFocus(self.handle, 0); + return [super resignFirstResponder]; +} @end // Delegates are weakly referenced from their peers. Nothing diff --git a/io/input/router.go b/io/input/router.go index 99962a1a2..4645eda8d 100644 --- a/io/input/router.go +++ b/io/input/router.go @@ -567,6 +567,14 @@ func (q *Router) changeState(e event.Event, state inputState, evts []taggedEvent e.event = de } } + for i := range evts { + e := &evts[i] + if fe, ok := e.event.(key.FocusEvent); ok { + if !fe.Focus { + state.keyState.focus = nil + } + } + } // Initialize the first change to contain the current state // and events that are bound for the current frame. if len(q.changes) == 0 { diff --git a/widget/editor.go b/widget/editor.go index 015c15de5..38783f037 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -289,6 +289,9 @@ func (e *Editor) processPointerEvent(gtx layout.Context, ev event.Event) (Editor Y: int(math.Round(float64(evt.Position.Y))), }) gtx.Execute(key.FocusCmd{Tag: e}) + if !e.ReadOnly { + gtx.Execute(key.SoftKeyboardCmd{Show: true}) + } if e.scroller.State() != gesture.StateFlinging { e.scrollCaret = true } @@ -395,7 +398,7 @@ func (e *Editor) processKey(gtx layout.Context) (EditorEvent, bool) { case key.FocusEvent: // Reset IME state. e.ime.imeState = imeState{} - if ke.Focus { + if ke.Focus && !e.ReadOnly { gtx.Execute(key.SoftKeyboardCmd{Show: true}) } case key.Event: