diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cad28130f..9c1248bf2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,33 @@ More detailed release notes can be found on the [releases page](https://github.c * Odd looking SelectEntry with long PlaceHolder (#4430) +## 2.5.3 - 12 December 2024 + +### Changed + +* Smoothly decelerate scroll on mobile +* Added Spanish translation + +### Fixed + +* Starting location can be wrong in file dialogs with custom repository (#5200) +* Improve how shortcut special keys for menu items are rendered on Windows and Linux (#5108) +* Blank page in Chrome for Android +* Mobile Entry: cursor arrows don't work (#5258) +* FileDialog does not handle relative file URIs well. (#5234) +* [Linux] Only change variant when color scheme changes +* [Linux] Window with list flickers in Wayland (#5133) +* Package command fails on OpenBSD (#5195) +* System theme fallback is not working with custom themes +* Translucency and images with Alpha channel (#1977) +* Performance regression when scrolling inside the file dialog (#4307) +* Empty but visible images consume high CPU on 2.4.x (#4345) +* Improved performance of text render caching +* nil pointer dereference in dialog.Resize() for color picker (#5236) +* Tiny files written in iOS may be empty +* Some SVG resources don't update appearance correctly with the theme (#3900) + + ## 2.5.2 - 15 October 2024 ### Fixed @@ -214,7 +241,6 @@ More detailed release notes can be found on the [releases page](https://github.c * Avoid memory leak in Android driver code * Entry Field on Android in Landscape Mode Shows "0" (#4036) * DocTabs Indicator remains visible after last tab is removed (#4220) -* Some SVG resources don't update appearance correctly with the theme (#3900) * Fix mobile simulation builds on OpenBSD * Fix alignment of menu button on mobile * Fix Compilation with Android NDK r26 diff --git a/cmd/fyne_demo/FyneApp.toml b/cmd/fyne_demo/FyneApp.toml index 672030555b..8ca47fa14c 100644 --- a/cmd/fyne_demo/FyneApp.toml +++ b/cmd/fyne_demo/FyneApp.toml @@ -2,7 +2,7 @@ Icon = "../../theme/icons/fyne.png" Name = "Fyne Demo" ID = "io.fyne.demo" - Version = "2.4.0" + Version = "2.5.3" Build = 11 [Source] diff --git a/cmd/hello/FyneApp.toml b/cmd/hello/FyneApp.toml index 12bf58730b..d9266e7b17 100644 --- a/cmd/hello/FyneApp.toml +++ b/cmd/hello/FyneApp.toml @@ -2,5 +2,5 @@ Icon = "../../theme/icons/fyne.png" Name = "Fyne Hello" ID = "io.fyne.hello" - Version = "2.4.0" + Version = "2.5.3" Build = 2 diff --git a/dialog/base.go b/dialog/base.go index 3105d36ba8..af713e9011 100644 --- a/dialog/base.go +++ b/dialog/base.go @@ -77,7 +77,9 @@ func (d *dialog) Refresh() { // Resize dialog, call this function after dialog show func (d *dialog) Resize(size fyne.Size) { d.desiredSize = size - d.win.Resize(size) + if d.win != nil { // could be called before popup is created! + d.win.Resize(size) + } } // SetDismissText allows custom text to be set in the dismiss button diff --git a/dialog/color_test.go b/dialog/color_test.go index b60eed07a5..7641c5d669 100644 --- a/dialog/color_test.go +++ b/dialog/color_test.go @@ -12,6 +12,24 @@ import ( "github.com/stretchr/testify/assert" ) +func TestColorDialog_Resize(t *testing.T) { + test.NewTempApp(t) + + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) + w.Resize(fyne.NewSize(1000, 800)) + + d := NewColorPicker("Color Picker", "Pick a Color", nil, w) + d.Resize(fyne.NewSize(800, 600)) + d.Show() + + size := d.dialog.content.Size() + + d.Resize(fyne.NewSize(900, 600)) + newSize := d.dialog.content.Size() + + assert.Equal(t, float32(100), newSize.Width-size.Width) +} + func TestColorDialog_Theme(t *testing.T) { test.NewTempApp(t) diff --git a/internal/driver/mobile/file_ios.m b/internal/driver/mobile/file_ios.m index 9ff83770da..01498ac282 100644 --- a/internal/driver/mobile/file_ios.m +++ b/internal/driver/mobile/file_ios.m @@ -48,6 +48,7 @@ bool iosExistsPath(const char* path) { void iosCloseFileWriter(void* handlePtr) { NSFileHandle* handle = (NSFileHandle*)handlePtr; + [handle synchronizeFile]; [handle closeFile]; } diff --git a/internal/svg/svg.go b/internal/svg/svg.go index 9300c06c03..9e78efc3cb 100644 --- a/internal/svg/svg.go +++ b/internal/svg/svg.go @@ -140,6 +140,7 @@ type pathObj struct { StrokeLineJoin string `xml:"stroke-linejoin,attr,omitempty"` StrokeDashArray string `xml:"stroke-dasharray,attr,omitempty"` D string `xml:"d,attr"` + Transform string `xml:"transform,attr,omitempty"` } type rectObj struct { @@ -155,6 +156,7 @@ type rectObj struct { Y string `xml:"y,attr,omitempty"` Width string `xml:"width,attr,omitempty"` Height string `xml:"height,attr,omitempty"` + Transform string `xml:"transform,attr,omitempty"` } type circleObj struct { @@ -169,6 +171,7 @@ type circleObj struct { CX string `xml:"cx,attr,omitempty"` CY string `xml:"cy,attr,omitempty"` R string `xml:"r,attr,omitempty"` + Transform string `xml:"transform,attr,omitempty"` } type ellipseObj struct { @@ -184,6 +187,7 @@ type ellipseObj struct { CY string `xml:"cy,attr,omitempty"` RX string `xml:"rx,attr,omitempty"` RY string `xml:"ry,attr,omitempty"` + Transform string `xml:"transform,attr,omitempty"` } type polygonObj struct { @@ -196,6 +200,7 @@ type polygonObj struct { StrokeLineJoin string `xml:"stroke-linejoin,attr,omitempty"` StrokeDashArray string `xml:"stroke-dasharray,attr,omitempty"` Points string `xml:"points,attr"` + Transform string `xml:"transform,attr,omitempty"` } type objGroup struct { @@ -207,6 +212,7 @@ type objGroup struct { StrokeLineCap string `xml:"stroke-linecap,attr,omitempty"` StrokeLineJoin string `xml:"stroke-linejoin,attr,omitempty"` StrokeDashArray string `xml:"stroke-dasharray,attr,omitempty"` + Transform string `xml:"transform,attr,omitempty"` Paths []*pathObj `xml:"path"` Circles []*circleObj `xml:"circle"` Ellipses []*ellipseObj `xml:"ellipse"` diff --git a/widget/menu_item.go b/widget/menu_item.go index 03f461291f..9eecdd082a 100644 --- a/widget/menu_item.go +++ b/widget/menu_item.go @@ -16,16 +16,15 @@ var _ fyne.Widget = (*menuItem)(nil) // menuItem is a widget for displaying a fyne.menuItem. type menuItem struct { widget.Base - Item *fyne.MenuItem - Parent *Menu + Item *fyne.MenuItem - alignment fyne.TextAlign - child *Menu + alignment fyne.TextAlign + child, parent *Menu } // newMenuItem creates a new menuItem. func newMenuItem(item *fyne.MenuItem, parent *Menu) *menuItem { - i := &menuItem{Item: item, Parent: parent} + i := &menuItem{Item: item, parent: parent} i.alignment = parent.alignment i.ExtendBaseWidget(i) return i @@ -35,7 +34,7 @@ func (i *menuItem) Child() *Menu { if i.Item.ChildMenu != nil && i.child == nil { child := NewMenu(i.Item.ChildMenu) child.Hide() - child.OnDismiss = i.Parent.Dismiss + child.OnDismiss = i.parent.Dismiss i.child = child } return i.child @@ -45,7 +44,7 @@ func (i *menuItem) Child() *Menu { // // Implements: fyne.Widget func (i *menuItem) CreateRenderer() fyne.WidgetRenderer { - th := i.Parent.Theme() + th := i.parent.Theme() v := fyne.CurrentApp().Settings().ThemeVariant() background := canvas.NewRectangle(th.Color(theme.ColorNameHover, v)) @@ -139,7 +138,7 @@ func (i *menuItem) activate() { if i.Child() != nil { i.Child().Show() } - i.Parent.activateItem(i) + i.parent.activateItem(i) } func (i *menuItem) activateLastSubmenu() bool { @@ -158,7 +157,7 @@ func (i *menuItem) deactivate() { if i.Child() != nil { i.Child().Hide() } - i.Parent.DeactivateChild() + i.parent.DeactivateChild() } func (i *menuItem) deactivateLastSubmenu() bool { @@ -173,7 +172,7 @@ func (i *menuItem) deactivateLastSubmenu() bool { } func (i *menuItem) isActive() bool { - return i.Parent.activeItem == i + return i.parent.activeItem == i } func (i *menuItem) isSubmenuOpen() bool { @@ -181,7 +180,7 @@ func (i *menuItem) isSubmenuOpen() bool { } func (i *menuItem) trigger() { - i.Parent.Dismiss() + i.parent.Dismiss() if i.Item.Action != nil { i.Item.Action() } @@ -209,7 +208,7 @@ type menuItemRenderer struct { } func (r *menuItemRenderer) Layout(size fyne.Size) { - th := r.i.Parent.Theme() + th := r.i.parent.Theme() innerPad := th.Size(theme.SizeNameInnerPadding) inlineIcon := th.Size(theme.SizeNameInlineIcon) @@ -258,7 +257,7 @@ func (r *menuItemRenderer) MinSize() fyne.Size { return r.minSize } - th := r.i.Parent.Theme() + th := r.i.parent.Theme() innerPad := th.Size(theme.SizeNameInnerPadding) inlineIcon := th.Size(theme.SizeNameInlineIcon) innerPad2 := innerPad * 2 @@ -282,7 +281,7 @@ func (r *menuItemRenderer) MinSize() fyne.Size { } func (r *menuItemRenderer) updateVisuals() { - th := r.i.Parent.Theme() + th := r.i.parent.Theme() v := fyne.CurrentApp().Settings().ThemeVariant() r.background.CornerRadius = th.Size(theme.SizeNameSelectionRadius) if fyne.CurrentDevice().IsMobile() { @@ -316,14 +315,14 @@ func (r *menuItemRenderer) Refresh() { } func (r *menuItemRenderer) checkSpace() float32 { - if r.i.Parent.containsCheck { + if r.i.parent.containsCheck { return theme.IconInlineSize() + theme.InnerPadding() } return 0 } func (r *menuItemRenderer) minSizeUnchanged() bool { - th := r.i.Parent.Theme() + th := r.i.parent.Theme() return !r.minSize.IsZero() && r.text.TextSize == th.Size(theme.SizeNameText) && @@ -343,7 +342,7 @@ func (r *menuItemRenderer) updateIcon(img *canvas.Image, rsc fyne.Resource) { } func (r *menuItemRenderer) refreshText(text *canvas.Text, shortcut bool) { - th := r.i.Parent.Theme() + th := r.i.parent.Theme() v := fyne.CurrentApp().Settings().ThemeVariant() text.TextSize = th.Size(theme.SizeNameText)