fyne-io / fyne

Cross platform GUI toolkit in Go inspired by Material Design
https://fyne.io/
Other
24.72k stars 1.37k forks source link

Focusing a widget inside AppTab|DocTabs.OnSelected doesn't work #3466

Open matwachich opened 1 year ago

matwachich commented 1 year ago

Checklist

Describe the bug

Calling .Focus(widget) inside AppTabs/DocTabs.OnSelected doesn't work.

Calling .Focus() inside a 500ms delayed goroutine works.

Something to do with tab changing animation?

How to reproduce

Just run the provided code. The Entry inside each tabitem should be focused on tab selection.

Screenshots

No response

Example code

package main

import (
    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/container"
    "fyne.io/fyne/v2/widget"
)

func main() {
    a := app.New()
    w := a.NewWindow("Test")

    e1 := widget.NewEntry()
    e2 := widget.NewEntry()

    tabs := container.NewAppTabs(
        container.NewTabItem("Entry 1", e1),
        container.NewTabItem("Entry 2", e2),
    )
    tabs.OnSelected = func(ti *container.TabItem) {
        //go func() {
        //time.Sleep(500 * time.Millisecond)
        w.Canvas().Focus(ti.Content.(fyne.Focusable))
        //}()
    }

    w.SetContent(tabs)
    w.Resize(fyne.NewSize(600, 400))
    w.CenterOnScreen()
    w.ShowAndRun()
}

Fyne version

2.3.0

Go compiler version

1.19.1

Operating system

Windows

Operating system version

10

Additional Information

No response

matwachich commented 1 year ago

Some info, hoping it will help: The fyne.Focusable is always hidden when tab.OnSelected is called.

image

This means that the name OnSelected is somewhat not true. The function should be called after all widgets contained in the tab item are called.

The problem is that OnSelected is called before tab.Refresh().


So current simple working workaround is just to call tab.Refresh() in the begining of OnSelected.

andydotxyz commented 1 year ago

I wonder if it is possible that selected and visible are being confused? The visual state of the UI may lag the data present, and selected is a data state that will later be shown in a refresh call?

matwachich commented 1 year ago

There is no confusion for me. Of course one is a state and the other is a visual, but the latter prevents the first from doing something (thus, focusing some widget upon tab selection).

It is not really critical (since you just need to Refresh the tab container before focusing), and if solving this means breaking other things, or just breaking code logic, then it doesn't worth it.

andydotxyz commented 1 year ago

What I mean is, the "unselected" is a data event - the user has made a selection - but what is visible changes based on a visual refresh so may indeed lag.

I think one possible fix is to track requests to focus for things not yet visible/added. This did previously work I think, but there was a change so that hidden or not-added container items could not be focused...

sdassow commented 5 months ago

Almost reported the same issue, then found this one, including the workaround, thanks @matwachich. Tested on the develop branch pulled a few minutes ago, and it's still the case.