Skip to content

Commit

Permalink
widget: make Button trigger unfocus when tapped.
Browse files Browse the repository at this point in the history
Fixes #5107.
  • Loading branch information
pierre committed Sep 18, 2024
1 parent c2cc495 commit 56adb5d
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
6 changes: 6 additions & 0 deletions widget/button.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ func (b *Button) Tapped(*fyne.PointEvent) {
b.tapAnimation()
b.Refresh()

if !b.focused {
// Grab the focus to unfocus any previous widget, then release it.
focusIfNotMobile(b.super())
b.FocusLost()
}

if onTapped := b.OnTapped; onTapped != nil {
onTapped()
}
Expand Down
44 changes: 44 additions & 0 deletions widget/button_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,47 @@ func TestButtonRenderer_TapAnimation(t *testing.T) {
button.tapAnim.Tick(0.5)
test.AssertImageMatches(t, "button/tap_animation.png", w.Canvas().Capture())
}

func TestButton_TappedFocus(t *testing.T) {
test.NewApp()
entry := NewEntry()
button := NewButton("ok", nil)
w := test.NewTempWindow(t, newCont(entry, button))

c := w.Canvas()
c.Focus(entry)
assert.True(t, entry.focused, "entry is not focused")

// NB. we cannot use test.Tap(button) as it handles focus,
// and we want to specifically test Button's handling of focus.
button.Tapped(&fyne.PointEvent{})
assert.False(t, entry.focused, "entry still has focus")
assert.False(t, button.focused, "button still has focus")
}

type cont struct {
BaseWidget
objects []fyne.CanvasObject
}

type contRenderer struct {
cont *cont
}

var _ fyne.CanvasObject = (*cont)(nil)

func newCont(objects ...fyne.CanvasObject) *cont {
c := &cont{objects: objects}
c.ExtendBaseWidget(c)
return c
}

func (c *cont) CreateRenderer() fyne.WidgetRenderer {
return &contRenderer{cont: c}
}

func (r *contRenderer) Destroy() {}
func (r *contRenderer) Layout(fyne.Size) {}
func (r *contRenderer) MinSize() fyne.Size { return fyne.NewSize(10, 10) }
func (r *contRenderer) Objects() []fyne.CanvasObject { return r.cont.objects }
func (r *contRenderer) Refresh() {}
2 changes: 1 addition & 1 deletion widget/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ func (c *checkRenderer) updateFocusIndicator(th fyne.Theme, v fyne.ThemeVariant)
}

func focusIfNotMobile(w fyne.Widget) {
if !fyne.CurrentDevice().IsMobile() {
if w != nil && !fyne.CurrentDevice().IsMobile() {
if c := fyne.CurrentApp().Driver().CanvasForObject(w); c != nil {
c.Focus(w.(fyne.Focusable))
}
Expand Down

0 comments on commit 56adb5d

Please sign in to comment.