-
Notifications
You must be signed in to change notification settings - Fork 134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
app,io,widget: [android/macos] fix focus issues #138
base: main
Are you sure you want to change the base?
Conversation
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]>
- (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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason to change: This is relative to the window, not the view. If you have multiple views in the same window, it used to incorrectly report that Gio had the focus.
if !e.ReadOnly { | ||
gtx.Execute(key.SoftKeyboardCmd{Show: true}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't make sense to request SoftKeyboard when it's ReadOnly. Maybe I need to do it on a separated commit?
func (w *window) ShowTextInput(show bool) { | ||
if show && !w.config.Focused { | ||
C.setFocus(w.view) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is macOS, which doesn't have SoftwareKeyboard. However, I didn't find any specific function to request focus, and adding a new function will require changes on multiple OSes, even as no-op
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why you need this here and not on other desktop platforms. Why can't C.setFocus
be called automatically in the cases where focus was lost?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's possible to call it when the GioView is clicked, and doesn't have focus. I don't think Gio should immediate request for Focus, because it's possible to have multiple non-Gio View in the same Window.
Extracted from #138 by inkeliz. Signed-off-by: Elias Naur <[email protected]>
Extracted from #138 by Inkeliz. References: https://todo.sr.ht/~eliasnaur/gio/591 Signed-off-by: Elias Naur <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extracted the non-controversial changes, leaving only the two that confuse me. Please rebase.
e := &evts[i] | ||
if fe, ok := e.event.(key.FocusEvent); ok { | ||
if !fe.Focus { | ||
state.keyState.focus = nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me this should be done in Router.processEvent
, near the lines
case key.EditEvent, key.FocusEvent, key.SelectionEvent:
var evts []taggedEvent
if f := state.focus; f != nil {
evts = append(evts, taggedEvent{tag: f, event: e})
}
q.changeState(e, state, evts)
But I'm not perfectly sure what use-case you're fixing. Can you add a test to io/input/key_test.go for my understanding and to guard against regressions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'm fixing is reseting the focus
when receiving key.FocusEvent
from "the OS".
Consider that you have one FocusCmd{Tag: TextArea}
. If Gio gets one FocusEvent
from "the OS" (say: macos), it will not remove the focus from TextArea
. That is the issue here.
So, this change changes the state
(state.keyState.focus
) to nil
when the FocusEvent is false
. Since it's messing with state
I use the changeState
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changeState
doesn't change state per se, it adds it to the list of states. A better name would be addStateChange
.
See https://github.com/gioui/gio/pull/138/files/101cf1aa478601e9c823f86a86b652b09d768a56#diff-c04c544d7677b4f40b53717995fb8f2e3d67212768e651e229ef2c020fc0d357L434 where state is changed by processEvent
, in response to a pointer.Event
.
func (w *window) ShowTextInput(show bool) { | ||
if show && !w.config.Focused { | ||
C.setFocus(w.view) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why you need this here and not on other desktop platforms. Why can't C.setFocus
be called automatically in the cases where focus was lost?
f8029f2
to
026d3f9
Compare
3d36537
to
74ccc9c
Compare
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