Skip to content

Commit

Permalink
Merge branch 'release/v2.1.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
andydotxyz committed Oct 22, 2021
2 parents c1df45f + bd4d100 commit d2da6c8
Show file tree
Hide file tree
Showing 63 changed files with 1,547 additions and 7,130 deletions.
27 changes: 26 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,32 @@
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.1 - 17 September 2021
## 2.1.1 - 22 October 2021

### Fixed

* Fix issue where table could select cells beyond data bound
* Some fast taps could be ignored (#2484)
* iOS app stops re-drawing mid-frame after a while (#950)
* Mobile simulation mode did not work on Apple M1 computers
* TextGrid background color can show gaps in render (#2493)
* Fix alignment of files in list view of file dialog
* Crash setting visible window on macOS to fixed size (#2488)
* fyne bundle ignores -name flag in windows (#2395)
* Lines with nil colour would crash renderer
* Android -nm tool not found with NDK 23 (#2498)
* Runtime panic because out of touchID (#2407)
* Long text in Select boxes overflows out of the box (#2522)
* Calling SetText on Label may not refresh correctly
* Menu can be triggered by # key but not always Alt
* Cursor position updates twice with delay (#2525)
* widgets freeze after being in background and then a crash upon pop-up menu (#2536)
* too many Refresh() calls may now cause visual artifacts in the List widget (#2548)
* Entry.SetText may panic if called on a multiline entry with selected text (#2482)
* TextGrid not always drawing correctly when resized (#2501)


## 2.1.0 - 17 September 2021

### Added

Expand Down
41 changes: 31 additions & 10 deletions app/preferences.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,29 @@ import (
type preferences struct {
*internal.InMemoryPreferences

prefLock sync.RWMutex
ignoreChange bool
prefLock sync.RWMutex
loadingInProgress bool
savedRecently bool
changedDuringSaving bool

app *fyneApp
}

// Declare conformity with Preferences interface
var _ fyne.Preferences = (*preferences)(nil)

func (p *preferences) resetIgnore() {
func (p *preferences) resetSavedRecently() {
go func() {
time.Sleep(time.Millisecond * 100) // writes are not always atomic. 10ms worked, 100 is safer.
p.prefLock.Lock()
p.ignoreChange = false
p.savedRecently = false
changedDuringSaving := p.changedDuringSaving
p.changedDuringSaving = false
p.prefLock.Unlock()

if changedDuringSaving {
p.save()
}
}()
}

Expand All @@ -38,9 +46,9 @@ func (p *preferences) save() error {

func (p *preferences) saveToFile(path string) error {
p.prefLock.Lock()
p.ignoreChange = true
p.savedRecently = true
p.prefLock.Unlock()
defer p.resetIgnore()
defer p.resetSavedRecently()
err := os.MkdirAll(filepath.Dir(path), 0700)
if err != nil { // this is not an exists error according to docs
return err
Expand Down Expand Up @@ -95,9 +103,18 @@ func (p *preferences) loadFromFile(path string) (err error) {
}()
decode := json.NewDecoder(file)

p.prefLock.Lock()
p.loadingInProgress = true
p.prefLock.Unlock()

p.InMemoryPreferences.WriteValues(func(values map[string]interface{}) {
err = decode.Decode(&values)
})

p.prefLock.Lock()
p.loadingInProgress = false
p.prefLock.Unlock()

return err
}

Expand All @@ -112,10 +129,14 @@ func newPreferences(app *fyneApp) *preferences {
}

p.AddChangeListener(func() {
p.prefLock.RLock()
shouldIgnoreChange := p.ignoreChange
p.prefLock.RUnlock()
if shouldIgnoreChange { // callback after loading, no need to save
p.prefLock.Lock()
shouldIgnoreChange := p.savedRecently || p.loadingInProgress
if p.savedRecently && !p.loadingInProgress {
p.changedDuringSaving = true
}
p.prefLock.Unlock()

if shouldIgnoreChange { // callback after loading file, or too many updates in a row
return
}

Expand Down
2 changes: 1 addition & 1 deletion app/preferences_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (a *fyneApp) storageRoot() string {
func (p *preferences) watch() {
watchFile(p.storagePath(), func() {
p.prefLock.RLock()
shouldIgnoreChange := p.ignoreChange
shouldIgnoreChange := p.savedRecently
p.prefLock.RUnlock()
if shouldIgnoreChange {
return
Expand Down
5 changes: 4 additions & 1 deletion cmd/fyne/internal/commands/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ func (i *Installer) install() error {
case "linux", "openbsd", "freebsd", "netbsd":
i.installDir = "/" // the tarball contains the structure starting at usr/local
case "windows":
dirName := p.name[:len(p.name)-4]
dirName := p.name
if filepath.Ext(p.name) == ".exe" {
dirName = p.name[:len(p.name)-4]
}
i.installDir = filepath.Join(os.Getenv("ProgramFiles"), dirName)
err := runAsAdminWindows("mkdir", "\"\""+i.installDir+"\"\"")
if err != nil {
Expand Down
9 changes: 8 additions & 1 deletion cmd/fyne/internal/commands/install_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,12 @@ func linkToStartMenu(path, name string) error {

func postInstall(i *Installer) error {
p := i.Packager
return linkToStartMenu(filepath.Join(i.installDir, filepath.Base(p.exe)), p.name[:len(p.name)-4])
appName := p.name
appExe := p.name
if filepath.Ext(p.name) == ".exe" {
appName = p.name[:len(p.name)-4]
} else {
appExe = appExe + ".exe"
}
return linkToStartMenu(filepath.Join(i.installDir, appExe), appName)
}
39 changes: 12 additions & 27 deletions cmd/fyne/internal/commands/package-windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@ package commands

import (
"image"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"

"fyne.io/fyne/v2/cmd/fyne/internal/templates"
ico "github.com/Kodeworks/golang-image-ico"
"github.com/josephspurrier/goversioninfo"
"github.com/pkg/errors"
"golang.org/x/mod/modfile"
"golang.org/x/mod/module"
"golang.org/x/sys/execabs"
)

Expand Down Expand Up @@ -106,37 +102,26 @@ func (p *Packager) packageWindows() error {
return errors.Wrap(err, "Failed to rebuild after adding metadata")
}

appPath := p.exe
appName := filepath.Base(p.exe)
if filepath.Base(p.exe) != p.name {
appName = p.name
if filepath.Ext(p.name) != ".exe" {
appName = appName + ".exe"
}
appPath = filepath.Join(filepath.Dir(p.exe), appName)
os.Rename(filepath.Base(p.exe), appName)
}

if p.install {
err := runAsAdminWindows("copy", "\"\""+p.exe+"\"\"", "\"\""+filepath.Join(p.dir, p.name)+"\"\"")
err := runAsAdminWindows("copy", "\"\""+appPath+"\"\"", "\"\""+filepath.Join(p.dir, appName)+"\"\"")
if err != nil {
return errors.Wrap(err, "Failed to run as administrator")
}
}
return nil
}

func calculateExeName(sourceDir, os string) string {
exeName := filepath.Base(sourceDir)
/* #nosec */
if data, err := ioutil.ReadFile(filepath.Join(sourceDir, "go.mod")); err == nil {
modulePath := modfile.ModulePath(data)
moduleName, _, ok := module.SplitPathVersion(modulePath)
if ok {
paths := strings.Split(moduleName, "/")
name := paths[len(paths)-1]
if name != "" {
exeName = name
}
}
}

if os == "windows" {
exeName = exeName + ".exe"
}

return exeName
}

func runAsAdminWindows(args ...string) error {
cmd := "\"/c\""

Expand Down
31 changes: 27 additions & 4 deletions cmd/fyne/internal/commands/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ package commands
import (
"flag"
"fmt"

// import image encodings
_ "image/jpeg"
_ "image/png"
_ "image/jpeg" // import image encodings
_ "image/png" // import image encodings
"io/ioutil"
"log"
"os"
"path/filepath"
Expand All @@ -15,6 +14,8 @@ import (

"github.com/pkg/errors"
"github.com/urfave/cli/v2"
"golang.org/x/mod/modfile"
"golang.org/x/mod/module"

"fyne.io/fyne/v2/cmd/fyne/internal/metadata"
"fyne.io/fyne/v2/cmd/fyne/internal/util"
Expand Down Expand Up @@ -296,6 +297,28 @@ func (p *Packager) validate() error {
return nil
}

func calculateExeName(sourceDir, os string) string {
exeName := filepath.Base(sourceDir)
/* #nosec */
if data, err := ioutil.ReadFile(filepath.Join(sourceDir, "go.mod")); err == nil {
modulePath := modfile.ModulePath(data)
moduleName, _, ok := module.SplitPathVersion(modulePath)
if ok {
paths := strings.Split(moduleName, "/")
name := paths[len(paths)-1]
if name != "" {
exeName = name
}
}
}

if os == "windows" {
exeName = exeName + ".exe"
}

return exeName
}

func isValidVersion(ver string) bool {
nums := strings.Split(ver, ".")
if len(nums) == 0 || len(nums) > 3 {
Expand Down
2 changes: 2 additions & 0 deletions cmd/fyne/internal/mobile/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ func (tc *ndkToolchain) Path(ndkRoot, toolName string) string {
switch toolName {
case "clang", "clang++":
pref = tc.ClangPrefix()
case "nm":
pref = "llvm"
default:
pref = tc.toolPrefix
}
Expand Down
55 changes: 30 additions & 25 deletions data/binding/queue_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package binding

import (
"fmt"
"os"
"runtime"
"sync"
Expand All @@ -12,19 +11,40 @@ import (
)

func TestMain(m *testing.M) {
testQueueLazyInit()
os.Exit(m.Run())
}

// TestQueryLazyInit resets the current unbounded func queue, and tests
// if the queue is lazy initialized.
//
// Note that this test may fail, if any of other tests in this package
// calls t.Parallel().
func TestQueueLazyInit(t *testing.T) {
if queue != nil { // Reset queues
queue.Close()
queue = nil
once = sync.Once{}
}

initialGoRoutines := runtime.NumGoroutine()

wg := sync.WaitGroup{}
wg.Add(1000)
for i := 0; i < 1000; i++ {
queueItem(func() { wg.Done() })
}
wg.Wait()

n := runtime.NumGoroutine()
if n > initialGoRoutines+2 {
t.Fatalf("unexpected number of goroutines after initialization, probably leaking: got %v want %v", n, initialGoRoutines+2)
}
}

func TestQueueItem(t *testing.T) {
called := 0
queueItem(func() {
called++
})
queueItem(func() {
called++
})

queueItem(func() { called++ })
queueItem(func() { called++ })
waitForItems()
assert.Equal(t, 2, called)
}
Expand All @@ -45,23 +65,8 @@ func TestMakeInfiniteQueue(t *testing.T) {
for i := 0; i < 2048; i++ {
queue.In() <- func() {}
}
close(queue.In())
queue.Close()

wg.Wait()
assert.Equal(t, 2048, c)
}

func testQueueLazyInit() {
initialGoRoutines := runtime.NumGoroutine()

wg := sync.WaitGroup{}
wg.Add(1000)
for i := 0; i < 1000; i++ {
go queueItem(func() { wg.Done() })
}
wg.Wait()
if runtime.NumGoroutine() != initialGoRoutines+2 {
fmt.Println("--- FAIL: testQueueLazyInit")
os.Exit(1)
}
}
2 changes: 1 addition & 1 deletion dialog/fileitem.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (s fileItemRenderer) Layout(size fyne.Size) {
s.text.Resize(fyne.NewSize(size.Width, fileTextSize))
s.text.Move(fyne.NewPos(fileInlineIconSize, (size.Height-s.text.MinSize().Height)/2))
}

s.text.Refresh()
}

func (s fileItemRenderer) MinSize() fyne.Size {
Expand Down

0 comments on commit d2da6c8

Please sign in to comment.