Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak when calling SetSystemTrayIcon() #3463

Open
2 tasks done
zangdale opened this issue Dec 8, 2022 · 3 comments
Open
2 tasks done

Memory leak when calling SetSystemTrayIcon() #3463

zangdale opened this issue Dec 8, 2022 · 3 comments
Labels
unverified A bug that has been reported but not verified

Comments

@zangdale
Copy link

zangdale commented Dec 8, 2022

Checklist

  • I have searched the issue tracker for open issues that relate to the same problem, before opening a new one.
  • This issue only relates to a single bug. I will open new issues for any other problems.

Describe the bug

连续的调用 SetSystemTrayIcon 会出现程序占用内存不断增大

How to reproduce

go func() {
			// TODO 存在内存泄露
			t := true
			for range time.NewTicker(time.Second).C {
				if t {
					desk.SetSystemTrayIcon(resourceAppIconPng)
				} else {
					desk.SetSystemTrayIcon(resource118104Png)
				}
				t = !t
			}
		}()

Screenshots

No response

Example code

package main

import (
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/driver/desktop"
	"fyne.io/fyne/v2/widget"
)

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

	m := &fyne.Menu{Label: "MyApp"}
	show := "Show"
	hide := "Hide"
	action := func(menu *fyne.MenuItem, desk desktop.App) func() {
		return func() {
			if menu.Label == show {
				w.Show()
				menu.Label = hide
				desk.SetSystemTrayIcon(resource118104Png)
			} else {
				w.Hide()
				menu.Label = show
				desk.SetSystemTrayIcon(resourceAppIconPng)
			}
			m.Refresh()
		}
	}
	showOrClose := &fyne.MenuItem{Label: "Hide"}

	if desk, ok := a.(desktop.App); ok {
		showOrClose.Action = action(showOrClose, desk)
		go func() {
			// TODO 存在内存泄露
			t := true
			for range time.NewTicker(time.Second).C {
				if t {
					desk.SetSystemTrayIcon(resourceAppIconPng)
				} else {
					desk.SetSystemTrayIcon(resource118104Png)
				}
				t = !t
			}
		}()

		m.Items = []*fyne.MenuItem{showOrClose}
		desk.SetSystemTrayMenu(m)
		desk.SetSystemTrayIcon(resourceAppIconPng)
	}

	w.SetContent(widget.NewLabel("Fyne System Tray"))
	w.SetCloseIntercept(func() {
		w.Close()
	})
	w.ShowAndRun()
}

Fyne version

v2.2.4

Go compiler version

1.19.1

Operating system

macOS

Operating system version

12.6

Additional Information

No response

@zangdale zangdale added the unverified A bug that has been reported but not verified label Dec 8, 2022
@Bluebugs
Copy link
Contributor

Bluebugs commented Dec 8, 2022

Google translate says: "Consecutive calls to SetSystemTrayIcon will cause the memory occupied by the program to increase continuously"

@Jacalz
Copy link
Member

Jacalz commented Dec 8, 2022

Please stick to English if possible. Most of us in the team do not speak Chinese.

@Jacalz Jacalz changed the title 连续调用 SetSystemTrayIcon(icon fyne.Resource) 会出现内存泄漏 Memory leak when calling SetSystemTrayIcon() Dec 8, 2022
@zangdale
Copy link
Author

change systray/systray_darwin.m

netbirdio/netbird#504
getlantern/systray#240
https://stackoverflow.com/questions/25860942/is-it-necessary-to-use-autoreleasepool-in-a-swift-program/25880106#25880106

void setIcon(const char* iconBytes, int length, bool template) {
  NSData* buffer = [NSData dataWithBytes: iconBytes length:length];
  @autoreleasepool {
    NSImage *image = [[NSImage alloc] initWithData:buffer];
    [image setSize:NSMakeSize(16, 16)];
    image.template = template;
    runInMainThread(@selector(setIcon:), (id)image);
  }
}

void setMenuItemIcon(const char* iconBytes, int length, int menuId, bool template) {
  NSData* buffer = [NSData dataWithBytes: iconBytes length:length];
  @autoreleasepool {
    NSImage *image = [[NSImage alloc] initWithData:buffer];
    [image setSize:NSMakeSize(16, 16)];
    image.template = template;
    NSNumber *mId = [NSNumber numberWithInt:menuId];
    runInMainThread(@selector(setMenuItemIcon:), @[image, (id)mId]);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
unverified A bug that has been reported but not verified
Projects
None yet
Development

No branches or pull requests

3 participants