fyne-io / fyne

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

Generated theme with theme tool causes random blank(white) dialogs and windows #3423

Closed roffe closed 1 year ago

roffe commented 1 year ago

Checklist

Describe the bug

At random times non master windows will just render as white content. I have not been able to reproduce it and i have tried changing order of resize, show, layout and tried everything I can to solve it

image

if I resize the defunct window the content starts showing

image

How to reproduce

clone EEP repo go run . press settings or help button and sometimes they will randomly be completely white inside and resizing them makes them show content again

Screenshots

No response

Example code

Code for project is here

https://github.com/Hirschmann-Koxha-GbR/eep/tree/master/gui

Fyne version

v2.2.4

Go compiler version

go1.19.3

Operating system

Windows

Operating system version

Windows 11 22H2 Build 22621.819

Additional Information

No response

roffe commented 1 year ago

It seems that it's some race condition in starting the app. once I get the white window effect. resizing it makes it paint, then I close it and open it again but now it's white with the new window size. Still no way to reproduce it, completely random when it happends, but it seems once the program is running, if you have not gotten any white windows then they will keep working

image

image

image

image

worth noteing maybe is that all new windows flash white quickly when they are created and drawn the first time

roffe commented 1 year ago

hmm it seems windows that i create new works but the re-used windows like settings and help which i Hide() instead of close is the ones bugging out

andydotxyz commented 1 year ago

hmm it seems windows that i create new works but the re-used windows like settings and help which i Hide() instead of close is the ones bugging out

Oh interesting, how does the window get re-shown after it is hiden?

andydotxyz commented 1 year ago

A white window means our graphics is not initiating or not getting the window context I think, as the background colour would be that dark grey.

roffe commented 1 year ago

on app start i have some structs like the following to create my windows

type settingsWindow struct {
    e                *EEPGui
    w                fyne.Window
    ignoreError      *widget.Check
    readSliderLabel  *widget.Label
    readSlider       *widget.Slider
    writeSliderLabel *widget.Label
    writeSlider      *widget.Slider
    updateButton     *widget.Button
}

they are in turn referenced in my app's main structure

type EEPGui struct {
    app   fyne.App
    state *appState
    mw    *mainWindow
    hw    *helpWindow
    sw    *settingsWindow
}

when i then want to show them i call the .w.Show() function and then i have a onclose interceptor that Hide() the window so i can re-use it to be shown again

roffe commented 1 year ago

Im making some experiments where i always create new windows and assign the window to my pointer while it's open, and then i check if that pointer is != nil then i call .SetFocus() to get the window to the foreground instead of opening a new.

The settings window stopped flashing white but the help window that contains multiple images still flashes briefly white before it paints even when creating a new window when i press my help button.

Nvidia 2080 RTX graphics card with 522.25 drivers.

I've gotten two friends on W11 and W10 to be able to get the white windows also but never anything where we can reproduce it.

Also this never happends to the main window. only the auxilliary windows i create outside the main window

andydotxyz commented 1 year ago

I understand that this cannot be reliably reproduced, but is there a minimal code sample that you can share where you've seen this behaviour?

roffe commented 1 year ago

Since I stopped trying to re-use windows with Show() and Hide() and always create a new one it it's not happened anymore.

I will try to see if I can make some code to try to trigger it

roffe commented 1 year ago

I take the above back.

I refactored my whole program to not use more than one window. now the native Fyne dialogues (dialogue.Show***) does the white box thing on some peoples computers

roffe commented 1 year ago

image

roffe commented 1 year ago

still unable to reproduce it in code. works on one machine, same binary next machine,always broken.

I've updated to Fyne 2.3.0 and propblem persists

xbojer commented 1 year ago

On my computer with roffe's software this bug always happen

andydotxyz commented 1 year ago

Is this shown with both the light and dark themes?

andydotxyz commented 1 year ago

Looking more at it there is a lot of custom painting going on here. If you use a standard dialog does the problem go away?

And/or can you provide the code that creates the erroneous screen? (Not just a link to a whole repository).

roffe commented 1 year ago

latest whitebox picture is produced with the following code

                dialog.ShowConfirm("Error reading CIM", "There was errors reading, view anyway?", func(ok bool) {
                    if ok {
                        m.docTab.Append(container.NewTabItemWithIcon(fmt.Sprintf("Raw read at %s", time.Now().Format("15:04:05")), theme.FileIcon(), newViewerView(m.e, fmt.Sprintf("failed read from %s", time.Now().Format(time.RFC1123Z)), rawBytes, true)))
                        m.appTabs.SelectIndex(0)
                        m.docTab.SelectIndex(len(m.docTab.Items) - 1)
                    }
                }, m)
roffe commented 1 year ago

we might have made a breakthrough

this theme is causing the white boxes


// Code generated by fyne-theme-generator

package gui

import (
    "image/color"

    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/theme"
)

type Theme struct{}

func (Theme) Color(c fyne.ThemeColorName, v fyne.ThemeVariant) color.Color {
    switch c {
    case theme.ColorNameBackground:
        return color.NRGBA{R: 0x30, G: 0x30, B: 0x30, A: 0xff}
    case theme.ColorNameButton:
        return color.Alpha16{A: 0x0}
    case theme.ColorNameDisabledButton:
        return color.NRGBA{R: 0x26, G: 0x26, B: 0x26, A: 0xff}
    case theme.ColorNameDisabled:
        return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x42}
    case theme.ColorNameError:
        return color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff}
    case theme.ColorNameFocus:
        return color.NRGBA{R: 0x21, G: 0x96, B: 0xf3, A: 0x7f}
    case theme.ColorNameForeground:
        return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}
    case theme.ColorNameHover:
        return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xf}
    case theme.ColorNameInputBackground:
        return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x19}
    case theme.ColorNamePlaceHolder:
        return color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff}
    case theme.ColorNamePressed:
        return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66}
    case theme.ColorNamePrimary:
        return color.NRGBA{R: 0x21, G: 0x96, B: 0xf3, A: 0xff}
    case theme.ColorNameScrollBar:
        return color.NRGBA{R: 0x0, G: 0x0, B: 0x0, A: 0x99}
    case theme.ColorNameShadow:
        return color.NRGBA{R: 0x0, G: 0x0, B: 0x0, A: 0x66}
    case theme.ColorNameSuccess:
        return color.NRGBA{R: 0x0, G: 0xf0, B: 0x0, A: 0x66}
    default:
        return theme.DefaultTheme().Color(c, v)
    }
}

func (Theme) Font(s fyne.TextStyle) fyne.Resource {
    if s.Monospace {
        return theme.DefaultTheme().Font(s)
    }
    if s.Bold {
        if s.Italic {
            return theme.DefaultTheme().Font(s)
        }
        return theme.DefaultTheme().Font(s)
    }
    if s.Italic {
        return theme.DefaultTheme().Font(s)
    }
    return theme.DefaultTheme().Font(s)
}

func (Theme) Icon(n fyne.ThemeIconName) fyne.Resource {
    return theme.DefaultTheme().Icon(n)
}

func (Theme) Size(s fyne.ThemeSizeName) float32 {
    switch s {
    case theme.SizeNameCaptionText:
        return 11
    case theme.SizeNameInlineIcon:
        return 20
    case theme.SizeNamePadding:
        return 2
    case theme.SizeNameScrollBar:
        return 16
    case theme.SizeNameScrollBarSmall:
        return 6
    case theme.SizeNameSeparatorThickness:
        return 0
    case theme.SizeNameText:
        return 14
    case theme.SizeNameInputBorder:
        return 2
    case theme.SizeNameInnerPadding:
        return 2
    default:
        return theme.DefaultTheme().Size(s)
    }
}
andydotxyz commented 1 year ago

Does it work as expected without your custom theme?

roffe commented 1 year ago

on my PC it always works after I stopped using multiple windows with custom theme. but on the ones with problems it works without custom theme and just using theme.Dark theme it seems

andydotxyz commented 1 year ago

Then I'm guessing the PCs that it doesn't work on have a different theme variant default (light vs dark) compared to your working PC. Your custom theme is missing some colours that the toolkit is providing - my guess is that ColorNameOverlayBackground would be most likely.

Closing as not an issue.

roffe commented 1 year ago

so the theme generator is most likely defunct. noted.

However there is something not adding up. Why did I get white boxes some times on my machine when using multiple Windows. and why does it happends some times on some machines and always on others.

Smells like a race condition somewhere

andydotxyz commented 1 year ago

Sorry I'm not sure what "theme generator" you are referring to - but if you are using a third party to generate code you will need to make sure the version it is designed for matches the version your app uses. I guess they are not up to date with our latest release...

vinser commented 1 year ago

Hi I have the same issue on Windows 10 22H2 When the app starts the single base window is empty. When the window is resized or when it is minimized and then maximized, all elements in the window become visible. No matter what theme is used custom or default. I built the app using MSYS2 and TDM-GCC the result was the same. On my SBC with Ubuntu arm64 it builds and works fyne.

Update:

This small code reproduce the issue

package main

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

func main() {
    a := app.New()

    tab := container.NewTabItemWithIcon("Choice", theme.GridIcon(), container.NewAdaptiveGrid(0))

    contentTabs := container.NewAppTabs(tab)
    contentTabs.SetTabLocation(container.TabLocationBottom)

    wMain := a.NewWindow("TABS")
    wMain.Resize(fyne.NewSize(1344, 756))
    wMain.CenterOnScreen()
    wMain.SetContent(contentTabs)
    wMain.ShowAndRun()
}

The cause of error was a grid with zero columns - NewAdaptiveGrid(0)

vinser commented 1 year ago

In my case this happens when current folder is empty so grid gets zero size. I think its better to solve this in fyne code because of different behavior on different OSes

andydotxyz commented 1 year ago

Please avoid commenting on closed issues. In the future if you want to report an issue open a new ticket.