Skip to content

Commit

Permalink
app,io,widget: [android/macos] fix focus issues
Browse files Browse the repository at this point in the history
This patch is intended to fix two issues related to focus and
software-keyboard.

The focus is now reseted if it's lost due to external event,
such as clicking on non-Gio window/activity/fragment.

The software-keyboard will now re-open when clicked, except
if it's ReadOnly.

On macOS it will request focus again if the focus is lose
due to another View in the same Window. However, currently,
it's done by using ShowTextInput.

Fixes: https://todo.sr.ht/~eliasnaur/gio/591

Signed-off-by: inkeliz <[email protected]>
  • Loading branch information
inkeliz committed Jun 9, 2024
1 parent e6da07a commit db28ac7
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 6 deletions.
11 changes: 10 additions & 1 deletion app/os_macos.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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) {}

Expand Down
20 changes: 16 additions & 4 deletions app/os_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions io/input/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 4 additions & 1 deletion widget/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit db28ac7

Please sign in to comment.