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

Support Tray Menus (Windows) #1521

Closed
leaanthony opened this issue Jul 3, 2022 · 29 comments
Closed

Support Tray Menus (Windows) #1521

leaanthony opened this issue Jul 3, 2022 · 29 comments
Assignees
Labels
Enhancement New feature or request Implemented in v3 TODO The issue is ready to be developed

Comments

@leaanthony
Copy link
Member

leaanthony commented Jul 3, 2022

Wails should support Tray Menus for all platforms. It should support the features appropriate to each platform, EG text for Mac, icons for all platforms, etc.

Other Platforms:

@leaanthony leaanthony self-assigned this Jul 3, 2022
@leaanthony leaanthony added Enhancement New feature or request TODO The issue is ready to be developed labels Jul 3, 2022
@leaanthony leaanthony moved this to 🆕 TODO in Wails Backlog Jul 3, 2022
@doc-war
Copy link

doc-war commented Aug 10, 2022

windows Tray(托盘)目前都没支持,非常不便

@ha-sante
Copy link

ha-sante commented Aug 24, 2022

Any ideas on what would be the right mode of implementation?

e.g Should we start off with using a stable package or implement it ourselves @leaanthony ?

I mean in terms of contributing to the wails project?

Seeing this as a candidate for the library package dependency. https://github.com/getlantern/systray

@leaanthony
Copy link
Member Author

Awesome that you'd like to contribute 🙏 Trays are literally the first cab off the rank post v2. There's some preliminary work in the exp branch if you want to have a look. I fear Linux may be a no-go with it as it's likely to need a library installed on the client machine because the Gnome project don't believe it should be there 🙄

@leaanthony leaanthony moved this to 🆕 TODO in Wails Backlog Sep 23, 2022
@leaanthony leaanthony moved this from 🆕 TODO to 🏗 In progress in Wails Backlog Sep 23, 2022
@leaanthony leaanthony moved this from 🏗 In progress to 🆕 TODO in Wails Backlog Sep 23, 2022
@leaanthony leaanthony moved this from 🆕 TODO to 🏗 In progress in Wails Backlog Sep 23, 2022
@leaanthony leaanthony added this to the v2.2.0 milestone Oct 16, 2022
@saul-data
Copy link

We would like to use this project (fantastic work btw) and have tray icon feature for the background workers for our cloud native ETL / data pipeline tool also written in Golang - https://github.com/dataplane-app/dataplane

@leaanthony When do you think this feature will be available?

@leaanthony
Copy link
Member Author

Congratulations on releasing dataplane! Looks cool. There are never ETAs on features, however this feature is currently in-progress. There is a PR open with RFC here: #1959. Is this time critical for you?

@saul-data
Copy link

We were hoping to release in two weeks. We need the tray icon for basic open and exit a background process. I also want to show to users that it is running in the background. Is there any icon functionality available? I am not sure I need menus, just the icon to open and close the window. Once the window is open, we can then exit the app. To open the window, we can just click or double click the icon.

@leaanthony
Copy link
Member Author

Multi platform tray icons will not be ready in 2 weeks unfortunately.

@saul-data
Copy link

Will any platforms be available? We are focusing on Windows right now. Mac?

@leaanthony
Copy link
Member Author

There's the PR I linked. That's where we are at.

@StephenBrown2
Copy link

Linux may be a no-go with it as it's likely to need a library installed on the client machine because the Gnome project don't believe it should be there roll_eyes

While it may require a library on Linux, I still think it's worth implementing something or at least giving a bit of boilerplate code to be able to have KStatusNotifierItem/AppIndicator support on Linux.

I understand you're working on Windows and Mac support first, but just wanted to put my vote in for Linux support, since we do have the capability of specifying dependencies, though maybe this is for dev only and not runtime? https://wails.io/docs/guides/linux-distro-support#adding-package-names

Thank you for the excellent project, and you have my sincerest gratitude for your effort!

@lyimmi
Copy link
Contributor

lyimmi commented Nov 11, 2022

Hi,

I think we could use Dbus with SystemNotifier/AppIndicator as our main implementaion. It seems to me that it could solve the problem on a big portion of the most used distros without depending on any installed C library. For example fyne-io only supports the DBus way.

I tried this on a few distros:

  • fedora latest (not working, default gnome)
  • fedora KDE (works)
  • kubuntu 22.04 (works)
  • kubuntu 20.04 (works)
  • ubuntu 22.04 gnome (works)
  • popOS 22.04 gnome (works)
  • linux mint cinnamon (works)
  • linux mint xfce (works)
  • linux mint mate (not working)

As a second option:
If we want (have the time and determination to implement them) we could maybe hide the fallback implementations behind a build flag as an optional dependency?

And if the DBus way is not available fallback to libayatana-appindicator and maybe libappindicator3 if its not available and throw a warning if neither is available. Tauri does the same thing. Electron simply depends on libappindicator1. In the documentation we could inform the developers that the packaging and distribution of the libraries is their job.

@leaanthony
Copy link
Member Author

I'm happy with this approach. If only linux had some common installer mechanism to make this easy 🤦

@lyimmi
Copy link
Contributor

lyimmi commented Nov 11, 2022

https://xkcd.com/927

I don't know if anyone is "assigned" to the linux part of the tray pr #1959, if you'd like @leaanthony I could pick it up in mid November.

@leaanthony
Copy link
Member Author

That would be amazing @lyimmi Thank you! 🙏

@leaanthony leaanthony removed this from the v2.2 milestone Nov 22, 2022
@leaanthony leaanthony added this to the v2.3.0 milestone Nov 22, 2022
@Aceix
Copy link

Aceix commented Nov 22, 2022

There's this fork also https://github.com/fyne-io/systray. It claims to remove GTK deps. might be worth looking at.
I tried it with a wails app I'm building and no issues on Ubuntu 22.04 (GNOME 42.5) so far. The app is still under development though

@lyimmi
Copy link
Contributor

lyimmi commented Nov 22, 2022

Yes, this is a Dbus implementation as well.

@leaanthony leaanthony changed the title Support Tray Menus Support Tray Menus (Windows) Dec 1, 2022
@leaanthony leaanthony removed this from the v2.4.0 milestone Dec 29, 2022
@TheFranconianCoder
Copy link

Currently I'm working on a background app, which should mostly sits in the tray. Are there plans, the WebView can actually be closed and re-started, instead of hide and show? To hide the WebView in such a scenario would be a waste of ressources.

@leaanthony
Copy link
Member Author

Will be possible in v3 which has a much better API for such things 👍

@lthon09
Copy link

lthon09 commented May 30, 2023

I've found a better fork of systray here, which supports left, right click and double (?) click: https://github.com/energye/systray

@TheFranconianCoder
Copy link

I've found a better fork of systray here, which supports left, right click and double (?) click: https://github.com/energye/systray

Used that before. Worked pretty well. 👍

@lthon09
Copy link

lthon09 commented May 30, 2023

I'm currently using it in a Wails project, it provides a much easier to use API and even extra click callbacks. Seamlessly integrates with Wails :)

@leaanthony
Copy link
Member Author

I'm glad there's a workaround for v2. We will have native support in v3 (already working pretty well for Mac and Windows)

@dami-i
Copy link

dami-i commented Jun 24, 2023

I'm currently using it in a Wails project, it provides a much easier to use API and even extra click callbacks. Seamlessly integrates with Wails :)

@lthon09 Would you mind giving me a glimpse on how you assembled the integration?

I'm glad there's a workaround for v2. We will have native support in v3 (already working pretty well for Mac and Windows)

@leaanthony I just stumbled upon a options.SystemTray and options.SystemTrayIcon with the help of intellisense. Is this fully implemented yet? I'm using v2.5.1.

@leaanthony
Copy link
Member Author

@leaanthony I just stumbled upon a options.SystemTray and options.SystemTrayIcon with the help of intellisense. Is this fully implemented yet? I'm using v2.5.1.

They were experiments. Ultimately, the v2 API is written specifically for single windows and that runs deep. I looked at adding it and it wasn't great so we've added it to v3 where the entire guts were built in a way to better support these features. A brave soul has made a project with it (even though it's alpha) and has screenshots here: https://github.com/duolabmeng6/go-qoq

@lthon09
Copy link

lthon09 commented Jun 24, 2023

I'm currently using it in a Wails project, it provides a much easier to use API and even extra click callbacks. Seamlessly integrates with Wails :)

@lthon09 Would you mind giving me a glimpse on how you assembled the integration?

It's just using some basic features of the package, create some menu items for showing and quitting the program. Here's some example code:

package main

import (
	"github.com/energye/systray"

	"github.com/wailsapp/wails/v2"
	"github.com/wailsapp/wails/v2/pkg/options"
	"github.com/wailsapp/wails/v2/pkg/runtime"
)

type _application struct {
	context _context.Context
}
var __application *_application

func systemTray() {
	systray.SetIcon([]byte()) // read the icon from a file

	show := systray.AddMenuItem("Show", "Show The Window")
	systray.AddSeparator()
	exit := systray.AddMenuItem("Exit", "Quit The Program")

	show.Click(func() {wailsRuntime.WindowShow(__application.context)})
	exit.Click(func() {os.Exit(0)})

	systray.SetOnClick(func() {wailsRuntime.WindowShow(__application.context)})
	systray.SetOnRClick(func(menu systray.IMenu) {menu.ShowMenu()})
}

func main() {
	__application = &_application{}
	wails.Run(&options.App{
		// ...

		OnStartup: __application.startUp,

		Bind: []interface{}{__application},
	})
}

func (application *_application) startUp(context _context.Context) {
	application.context = context
	systray.Run(systemTray, func() {})
}

It integrates with Wails really well. Sorry if my code looks unclean!

@leaanthony
Copy link
Member Author

Closing this as it's intended for v3 and there's no more work to be done on it.

@W1M0R W1M0R mentioned this issue Sep 18, 2023
2 tasks
@nsainaney
Copy link

I'm currently using it in a Wails project, it provides a much easier to use API and even extra click callbacks. Seamlessly integrates with Wails :)

@lthon09 Would you mind giving me a glimpse on how you assembled the integration?

It's just using some basic features of the package, create some menu items for showing and quitting the program. Here's some example code:

package main

import (
	"github.com/energye/systray"

	"github.com/wailsapp/wails/v2"
	"github.com/wailsapp/wails/v2/pkg/options"
	"github.com/wailsapp/wails/v2/pkg/runtime"
)

type _application struct {
	context _context.Context
}
var __application *_application

func systemTray() {
	systray.SetIcon([]byte()) // read the icon from a file

	show := systray.AddMenuItem("Show", "Show The Window")
	systray.AddSeparator()
	exit := systray.AddMenuItem("Exit", "Quit The Program")

	show.Click(func() {wailsRuntime.WindowShow(__application.context)})
	exit.Click(func() {os.Exit(0)})

	systray.SetOnClick(func() {wailsRuntime.WindowShow(__application.context)})
	systray.SetOnRClick(func(menu systray.IMenu) {menu.ShowMenu()})
}

func main() {
	__application = &_application{}
	wails.Run(&options.App{
		// ...

		OnStartup: __application.startUp,

		Bind: []interface{}{__application},
	})
}

func (application *_application) startUp(context _context.Context) {
	application.context = context
	systray.Run(systemTray, func() {})
}

It integrates with Wails really well. Sorry if my code looks unclean!

The above doesn't work as wails and energye/systray both have an AppDelegate on MacOS and it results in a linker error (see below). Were you able to get it working on Mac?

running cc failed: exit status 1
ld: warning: ignoring duplicate libraries: '-lobjc'
duplicate symbol '_OBJC_METACLASS_$_AppDelegate' in:
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000002.o
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000026.o
duplicate symbol '_OBJC_CLASS_$_AppDelegate' in:
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000002.o
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000026.o
ld: 2 duplicate symbols```

@lthon09
Copy link

lthon09 commented Feb 13, 2024

I'm currently using it in a Wails project, it provides a much easier to use API and even extra click callbacks. Seamlessly integrates with Wails :)

@lthon09 Would you mind giving me a glimpse on how you assembled the integration?

It's just using some basic features of the package, create some menu items for showing and quitting the program. Here's some example code:

package main

import (
	"github.com/energye/systray"

	"github.com/wailsapp/wails/v2"
	"github.com/wailsapp/wails/v2/pkg/options"
	"github.com/wailsapp/wails/v2/pkg/runtime"
)

type _application struct {
	context _context.Context
}
var __application *_application

func systemTray() {
	systray.SetIcon([]byte()) // read the icon from a file

	show := systray.AddMenuItem("Show", "Show The Window")
	systray.AddSeparator()
	exit := systray.AddMenuItem("Exit", "Quit The Program")

	show.Click(func() {wailsRuntime.WindowShow(__application.context)})
	exit.Click(func() {os.Exit(0)})

	systray.SetOnClick(func() {wailsRuntime.WindowShow(__application.context)})
	systray.SetOnRClick(func(menu systray.IMenu) {menu.ShowMenu()})
}

func main() {
	__application = &_application{}
	wails.Run(&options.App{
		// ...

		OnStartup: __application.startUp,

		Bind: []interface{}{__application},
	})
}

func (application *_application) startUp(context _context.Context) {
	application.context = context
	systray.Run(systemTray, func() {})
}

It integrates with Wails really well. Sorry if my code looks unclean!

The above doesn't work as wails and energye/systray both have an AppDelegate on MacOS and it results in a linker error (see below). Were you able to get it working on Mac?

running cc failed: exit status 1
ld: warning: ignoring duplicate libraries: '-lobjc'
duplicate symbol '_OBJC_METACLASS_$_AppDelegate' in:
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000002.o
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000026.o
duplicate symbol '_OBJC_CLASS_$_AppDelegate' in:
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000002.o
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000026.o
ld: 2 duplicate symbols```


Unfortunately no I haven't tried anything on Mac and this code was from really long ago.

@zhufucdev
Copy link

I'm currently using it in a Wails project, it provides a much easier to use API and even extra click callbacks. Seamlessly integrates with Wails :)

@lthon09 Would you mind giving me a glimpse on how you assembled the integration?

It's just using some basic features of the package, create some menu items for showing and quitting the program. Here's some example code:

package main

import (
	"github.com/energye/systray"

	"github.com/wailsapp/wails/v2"
	"github.com/wailsapp/wails/v2/pkg/options"
	"github.com/wailsapp/wails/v2/pkg/runtime"
)

type _application struct {
	context _context.Context
}
var __application *_application

func systemTray() {
	systray.SetIcon([]byte()) // read the icon from a file

	show := systray.AddMenuItem("Show", "Show The Window")
	systray.AddSeparator()
	exit := systray.AddMenuItem("Exit", "Quit The Program")

	show.Click(func() {wailsRuntime.WindowShow(__application.context)})
	exit.Click(func() {os.Exit(0)})

	systray.SetOnClick(func() {wailsRuntime.WindowShow(__application.context)})
	systray.SetOnRClick(func(menu systray.IMenu) {menu.ShowMenu()})
}

func main() {
	__application = &_application{}
	wails.Run(&options.App{
		// ...

		OnStartup: __application.startUp,

		Bind: []interface{}{__application},
	})
}

func (application *_application) startUp(context _context.Context) {
	application.context = context
	systray.Run(systemTray, func() {})
}

It integrates with Wails really well. Sorry if my code looks unclean!

The above doesn't work as wails and energye/systray both have an AppDelegate on MacOS and it results in a linker error (see below). Were you able to get it working on Mac?

running cc failed: exit status 1
ld: warning: ignoring duplicate libraries: '-lobjc'
duplicate symbol '_OBJC_METACLASS_$_AppDelegate' in:
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000002.o
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000026.o
duplicate symbol '_OBJC_CLASS_$_AppDelegate' in:
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000002.o
    /private/var/folders/0v/0fvf17zn0q95mlsp1pp7sz3m0000gn/T/go-link-233777249/000026.o
ld: 2 duplicate symbols```

This fork contains the modification you wanted.

fyne-io/systray@6539193

It's not released though, so perhaps you want to add it to your project's submodule and replace the go module with it

git submodule add https://github.com/fyne-io/systray.git systray
echo 'replace fyne.io/systray => ./systray' >> go.mod

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement New feature or request Implemented in v3 TODO The issue is ready to be developed
Projects
Status: 🏗 In progress
Development

No branches or pull requests