diff --git a/widget/button.go b/widget/button.go index c508bc0013..9bbcf7fc35 100644 --- a/widget/button.go +++ b/widget/button.go @@ -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() } diff --git a/widget/button_internal_test.go b/widget/button_internal_test.go index 6c00cb25d0..92e1eb4f70 100644 --- a/widget/button_internal_test.go +++ b/widget/button_internal_test.go @@ -235,3 +235,50 @@ 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) { + if fyne.CurrentDevice().IsMobile() { + return + } + 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() {} diff --git a/widget/check.go b/widget/check.go index 22cf72d465..0d850f2432 100644 --- a/widget/check.go +++ b/widget/check.go @@ -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)) }