Skip to content

Commit

Permalink
Merge branch 'release/v2.3.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
andydotxyz committed Feb 13, 2023
2 parents 8c25095 + 30e7cb8 commit 5496b35
Show file tree
Hide file tree
Showing 49 changed files with 681 additions and 135 deletions.
30 changes: 30 additions & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,36 @@
This file lists the main changes with each version of the Fyne toolkit.
More detailed release notes can be found on the [releases page](https://github.com/fyne-io/fyne/releases).

## 2.3.1 - 13 February 2023

### Changed

* Pad app version to ensure Windows packages correctly (#3638)

### Fixed

* Custom shortcuts with fyne.KeyTab is not working (#3087)
* Running a systray app with root privileges resulted in panic (#3120)
* Markdown image with no title is not parsed (#3577)
* Systray app on macOS panic when started while machine sleeps (#3609)
* Runtime error with VNC on RaspbianOS (#2972)
* Hovered background in List widget isn't reset when scrolling reuses an existing list item (#3584)
* cmd/fyne package can't find FyneApp.toml when -src option has given (#3459)
* TextWrapWord will cause crash in RichText unverified (#3498)
* crash in widget.(*RichText).lineSizeToColumn (#3292)
* Crash in widget.(*Entry).SelectedText (#3290)
* Crash in widget.(*RichText).updateRowBounds.func1 (#3291)
* window is max size at all times (#3507)
* systray.Quit() is not called consistently when the app is closing (#3597)
* Software rendering would ignore scale for text
* crash when minimize a window which contains a stroked rectangle (#3552)
* Menu item would not appear disabled initially
* Wrong icon colour for danger and warning buttons
* Embedding Fyne apps in iFrame alignment issue
* Generated metadata can be in wrong directory
* Android RootURI may not exist when used for storage (#3207)


## 2.3.0 - 24 December 2022

### Added
Expand Down
5 changes: 5 additions & 0 deletions app/app.go
Expand Up @@ -4,6 +4,7 @@
package app // import "fyne.io/fyne/v2/app"

import (
"os"
"strconv"
"sync/atomic"
"time"
Expand Down Expand Up @@ -130,6 +131,10 @@ func makeStoreDocs(id string, p fyne.Preferences, s *store) *internal.Docs {
if pref, ok := p.(interface{ load() }); ok {
pref.load()
}
err := os.MkdirAll(s.a.storageRoot(), 0755) // make the space before anyone can use it
if err != nil {
fyne.LogError("Failed to create app storage space", err)
}

root, _ := s.docRootURI()
return &internal.Docs{RootDocURI: root}
Expand Down
2 changes: 1 addition & 1 deletion app/app_xdg.go
Expand Up @@ -48,7 +48,7 @@ func findFreedestktopColorScheme() fyne.ThemeVariant {
"color-scheme",
)
if call.Err != nil {
fyne.LogError("failed to read theme variant from D-Bus", call.Err)
// many desktops don't have this exported yet
return theme.VariantDark
}

Expand Down
22 changes: 22 additions & 0 deletions app/storage_test.go
@@ -0,0 +1,22 @@
package app

import (
"testing"

"github.com/stretchr/testify/assert"

"fyne.io/fyne/v2/internal"
)

func TestStore_RootURI(t *testing.T) {
id := "io.fyne.test"
a := &fyneApp{uniqueID: id}
d := makeStoreDocs(id, &internal.InMemoryPreferences{}, &store{a: a})

w, err := d.Create("test")
assert.Nil(t, err)
err = w.Close()
assert.Nil(t, err)
err = d.Remove("test")
assert.Nil(t, err)
}
86 changes: 77 additions & 9 deletions cmd/fyne/internal/commands/build.go
Expand Up @@ -90,6 +90,7 @@ func Build() *cli.Command {
// Build parse the tags and start building
func (b *Builder) Build() error {
if b.srcdir != "" {
b.srcdir = util.EnsureAbsPath(b.srcdir)
dirStat, err := os.Stat(b.srcdir)
if err != nil {
return err
Expand Down Expand Up @@ -197,14 +198,19 @@ func (b *Builder) build() error {
}
}

srcdir, err := b.computeSrcDir(fyneGoModRunner)
if err != nil {
return err
}

if b.icon == "" {
defaultIcon := filepath.Join(b.srcdir, "Icon.png")
defaultIcon := filepath.Join(srcdir, "Icon.png")
if util.Exists(defaultIcon) {
b.icon = defaultIcon
}
}

close, err := injectMetadataIfPossible(fyneGoModRunner, b.srcdir, b.appData, createMetadataInitFile)
close, err := injectMetadataIfPossible(fyneGoModRunner, srcdir, b.appData, createMetadataInitFile)
if err != nil {
fyne.LogError("Failed to inject metadata init file, omitting metadata", err)
} else if close != nil {
Expand All @@ -219,20 +225,24 @@ func (b *Builder) build() error {
appendEnv(&env, "CGO_LDFLAGS", "-mmacosx-version-min=10.11")
}

ldFlags := extractLdflagsFromGoFlags()
if !isWeb(goos) {
env = append(env, "CGO_ENABLED=1") // in case someone is trying to cross-compile...

if b.release {
ldFlags += " -s -w"
args = append(args, "-trimpath")
}

if goos == "windows" {
if b.release {
args = append(args, "-ldflags", "-s -w -H=windowsgui", "-trimpath")
} else {
args = append(args, "-ldflags", "-H=windowsgui ")
}
} else if b.release {
args = append(args, "-ldflags", "-s -w", "-trimpath")
ldFlags += " -H=windowsgui"
}
}

if len(ldFlags) > 0 {
args = append(args, "-ldflags", strings.TrimSpace(ldFlags))
}

if b.target != "" {
args = append(args, "-o", b.target)
}
Expand Down Expand Up @@ -282,9 +292,31 @@ func (b *Builder) build() error {
return err
}

func (b *Builder) computeSrcDir(fyneGoModRunner runner) (string, error) {
if b.goPackage == "" || b.goPackage == "." {
return b.srcdir, nil
}

srcdir := b.srcdir
if strings.HasPrefix(b.goPackage, "."+string(os.PathSeparator)) ||
strings.HasPrefix(b.goPackage, ".."+string(os.PathSeparator)) {
srcdir = filepath.Join(srcdir, b.goPackage)
} else if strings.HasPrefix(b.goPackage, string(os.PathSeparator)) {
srcdir = b.goPackage
} else {
return "", fmt.Errorf("unrecognized go package: %s", b.goPackage)
}
return srcdir, nil
}

func createMetadataInitFile(srcdir string, app *appData) (func(), error) {
data, err := metadata.LoadStandard(srcdir)
if err == nil {
// When icon path specified in metadata file, we should make it relative to metadata file
if data.Details.Icon != "" {
data.Details.Icon = util.MakePathRelativeTo(srcdir, data.Details.Icon)
}

app.mergeMetadata(data)
}

Expand Down Expand Up @@ -357,3 +389,39 @@ func appendEnv(env *[]string, varName, value string) {

*env = append(*env, varName+"="+value)
}

func extractLdflagsFromGoFlags() string {
goFlags := os.Getenv("GOFLAGS")

ldFlags, goFlags := extractLdFlags(goFlags)
if goFlags != "" {
os.Setenv("GOFLAGS", goFlags)
} else {
os.Unsetenv("GOFLAGS")
}

return ldFlags
}

func extractLdFlags(goFlags string) (string, string) {
if goFlags == "" {
return "", ""
}

flags := strings.Fields(goFlags)
ldflags := ""
newGoFlags := ""

for _, flag := range flags {
if strings.HasPrefix(flag, "-ldflags=") {
ldflags += strings.TrimPrefix(flag, "-ldflags=") + " "
} else {
newGoFlags += flag + " "
}
}

ldflags = strings.TrimSpace(ldflags)
newGoFlags = strings.TrimSpace(newGoFlags)

return ldflags, newGoFlags
}
53 changes: 53 additions & 0 deletions cmd/fyne/internal/commands/build_test.go
Expand Up @@ -2,6 +2,8 @@ package commands

import (
"fmt"
"os"
"path/filepath"
"runtime"
"testing"

Expand Down Expand Up @@ -230,6 +232,36 @@ func Test_BuildWasmOldVersion(t *testing.T) {
wasmBuildTest.verifyExpectation()
}

func Test_BuildLinuxReleaseVersion(t *testing.T) {
relativePath := "." + string(os.PathSeparator) + filepath.Join("cmd", "terminal")

expected := []mockRunner{
{
expectedValue: expectedValue{args: []string{"mod", "edit", "-json"}},
mockReturn: mockReturn{
ret: []byte("{ \"Module\": { \"Path\": \"fyne.io/fyne/v2\"} }"),
},
},
{
expectedValue: expectedValue{
args: []string{"build", "-trimpath", "-ldflags", "-s -w", "-tags", "release", relativePath},
env: []string{"CGO_ENABLED=1", "GOOS=linux"},
osEnv: true,
dir: "myTest",
},
mockReturn: mockReturn{
ret: []byte(""),
},
},
}

linuxBuildTest := &testCommandRuns{runs: expected, t: t}
b := &Builder{appData: &appData{}, os: "linux", srcdir: "myTest", release: true, runner: linuxBuildTest, goPackage: relativePath}
err := b.build()
assert.Nil(t, err)
linuxBuildTest.verifyExpectation()
}

type jsonTest struct {
expected bool
json []byte
Expand Down Expand Up @@ -281,3 +313,24 @@ func Test_AppendEnv(t *testing.T) {
assert.Equal(t, "foo2=baz2", env[3])
}
}

type extractTest struct {
value string
wantLdFlags string
wantGoFlags string
}

func Test_ExtractLdFlags(t *testing.T) {
goFlagsTests := []extractTest{
{"-ldflags=-w", "-w", ""},
{"-ldflags=-s", "-s", ""},
{"-ldflags=-w -ldflags=-s", "-w -s", ""},
{"-mod=vendor", "", "-mod=vendor"},
}

for _, test := range goFlagsTests {
ldFlags, goFlags := extractLdFlags(test.value)
assert.Equal(t, test.wantLdFlags, ldFlags)
assert.Equal(t, test.wantGoFlags, goFlags)
}
}
2 changes: 1 addition & 1 deletion cmd/fyne/internal/commands/package-unix.go
Expand Up @@ -68,7 +68,7 @@ func (p *Packager) packageUNIX() error {
}

var buf bytes.Buffer
tarCmd := execabs.Command("tar", "-Jcf", p.Name+".tar.xz", "-C", tempDir, "usr", "Makefile")
tarCmd := execabs.Command("tar", "-Jcf", filepath.Join(p.dir, p.Name+".tar.xz"), "-C", filepath.Join(p.dir, tempDir), "usr", "Makefile")
tarCmd.Stderr = &buf
if err = tarCmd.Run(); err != nil {
return fmt.Errorf("failed to create archive with tar: %s - %w", buf.String(), err)
Expand Down
10 changes: 10 additions & 0 deletions cmd/fyne/internal/commands/package-util-mock_test.go
Expand Up @@ -12,6 +12,8 @@ var utilCopyFileMock func(source string, target string) error
var utilCopyExeFileMock func(src, tgt string) error
var utilWriteFileMock func(target string, data []byte) error
var utilEnsureSubDirMock func(parent, name string) string
var utilEnsureAbsPathMock func(path string) string
var utilMakePathRelativeToMock func(root, path string) string

var utilRequireAndroidSDKMock func() error
var utilAndroidBuildToolsPathMock func() string
Expand Down Expand Up @@ -139,6 +141,14 @@ func (m mockUtil) EnsureSubDir(parent, name string) string {
return utilEnsureSubDirMock(parent, name)
}

func (m mockUtil) EnsureAbsPath(path string) string {
return utilEnsureAbsPathMock(path)
}

func (m mockUtil) MakePathRelativeTo(root, path string) string {
return utilMakePathRelativeToMock(root, path)
}

func (m mockUtil) RequireAndroidSDK() error {
return utilRequireAndroidSDKMock()
}
Expand Down
10 changes: 10 additions & 0 deletions cmd/fyne/internal/commands/package-util.go
Expand Up @@ -12,6 +12,8 @@ type packagerUtil interface {
CopyExeFile(src, tgt string) error
WriteFile(target string, data []byte) error
EnsureSubDir(parent, name string) string
EnsureAbsPath(path string) string
MakePathRelativeTo(root, path string) string

RequireAndroidSDK() error
AndroidBuildToolsPath() string
Expand Down Expand Up @@ -43,6 +45,14 @@ func (d defaultUtil) EnsureSubDir(parent, name string) string {
return realUtil.EnsureSubDir(parent, name)
}

func (d defaultUtil) EnsureAbsPath(path string) string {
return realUtil.EnsureAbsPath(path)
}

func (d defaultUtil) MakePathRelativeTo(root, path string) string {
return realUtil.MakePathRelativeTo(root, path)
}

func (d defaultUtil) RequireAndroidSDK() error {
return realUtil.RequireAndroidSDK()
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/fyne/internal/commands/package-windows.go
Expand Up @@ -115,7 +115,7 @@ func (p *Packager) packageWindows() error {
if filepath.Ext(p.Name) != ".exe" {
appName = appName + ".exe"
}
appPath = filepath.Join(filepath.Dir(p.exe), appName)
appPath = filepath.Join(p.dir, appName)
os.Rename(filepath.Base(p.exe), appName)
}

Expand Down

0 comments on commit 5496b35

Please sign in to comment.