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

Add system tray support #283

Closed
jiajunhuang opened this issue May 30, 2019 · 47 comments
Closed

Add system tray support #283

jiajunhuang opened this issue May 30, 2019 · 47 comments
Assignees
Labels
Bounty Tickets with this label rewards core contributors for completion future Features that might take a while to be sheduled Hacktoberfest

Comments

@jiajunhuang
Copy link

sometimes I need the app to minimize, and stay in the system tray, will fyne support system tray?

@andydotxyz andydotxyz added this to To do in Full Framework via automation May 30, 2019
@andydotxyz andydotxyz added the future Features that might take a while to be sheduled label May 30, 2019
@andydotxyz
Copy link
Member

Yes it will, at some point. Probably not in 1.1 or 1.2 but I would like to see it added soon after.

@epver
Copy link

epver commented Jul 19, 2019

I use systray to achieve this function, first transition

@ergoz
Copy link

ergoz commented Aug 8, 2019

+1
i need to create app with only system tray. But systray package cant create multi-level menu

@andydotxyz
Copy link
Member

Currently we don't have sub-menu support either.
We should add it soon, though I don't think it has a ticket so I will add one now.

Systray will come :)

@pkk-code
Copy link

I use systray to achieve this function, first transition

When i use systray and fyne. It works perfectly fine on windows OS, but fails on Mac OS. Is there a workaround to this problem? it seems its caused by runtime.LockOSThread() used by fyne and systray in the main.

Stack trace:

2020-05-12 21:02:57.559 main[12053:8552769] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /BuildRoot/Library/Caches/com.apple.xbs/Sources/Foundation/Foundation-1455.12/Foundation/Misc.subproj/NSUndoManager.m:361
2020-05-12 21:02:57.560 main[12053:8552769] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff363c8d7b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fff5d664c76 objc_exception_throw + 48
2 CoreFoundation 0x00007fff363ceb12 +[NSException raise:format:arguments:] + 98
3 Foundation 0x00007fff384faa30 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
4 Foundation 0x00007fff38489624 +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 469
5 AppKit 0x00007fff338ce936 -[NSApplication run] + 997
6 main 0x0000000004494b30 nativeLoop + 160
7 main 0x0000000004493903 _cgo_cafa63f1ae52_Cfunc_nativeLoop + 35
8 main 0x0000000004064200 runtime.asmcgocall + 112
)

@andydotxyz
Copy link
Member

macOS requires that code manipulating graphical elements run on the main thread. Do these things must run within the main() goroutine. Future versions of Fyne will be enforcing this to ensure cross platform consistency.

@andydotxyz
Copy link
Member

Submenu support is now in so it seeme likely that we could include systray in 2.0 late this year

@Jacalz Jacalz changed the title will fyne add system tray support? Add system tray support Dec 9, 2020
@izturn
Copy link

izturn commented Jan 5, 2021

any progress ?

@andydotxyz
Copy link
Member

No, sorry. 2.0 is due this month but we are really up against it and late last year really did not exactly go according to plan (as for many people).

@owmo-dev
Copy link

Does anyone have a workaround/suggestion for being able to use systray right now? My use case is an always persistent tray that can launch one or more fyne windows, but I haven't had much luck yet getting them working together.

@andydotxyz
Copy link
Member

You will need a system tray API that does not require blocking the main thread @grantmoore3d.
Once you have found one of them it should just work.

@andydotxyz
Copy link
Member

Sadly it looks like we will have to implement this from scratch as the Linux implementations all seem to use GTK/Qt.
Too much work to fit into 2.1 at this stage sadly.

@dawei101
Copy link

https://github.com/getlantern/systray

The systray repo have already done these work, why don't we merge from it.

@changkun
Copy link
Member

I think we'd more like to have a decent API set rather than using it directly merging it from the others.

Maybe, we could have something like fyne.io/x/tray as a fork of that package, that collaborate with the existing fyne codebase (which resolves the mainthread issue), No compatibility guarantee though, purely experimental.

@andydotxyz
Copy link
Member

We cannot use tools like systray as they bring in external dependencies (like GTK+ on Linux)

@changkun
Copy link
Member

We cannot use tools like systray as they bring in external dependencies (like GTK+ on Linux)

For experimental purposes, we may have it work with external dependencies first (then rewrite it afterward)?

@andydotxyz
Copy link
Member

I don't think that depending on another widget toolkit is a good idea, even in the short term.
You will have to solve problems (like threading) that are not a worry if we use our code.

@changkun
Copy link
Member

depending on another widget toolkit

Not really sure (because I haven't program any tray application yet) the main repository will depend on an external. But ideally, it should be like a standalone package where people may:

import "fyne.io/x/tray"

When the design converges to a fixed point, the only change might be:

-import "fyne.io/x/tray"
+import "fyne.io/fyne/v2/tray"

@andydotxyz andydotxyz added the Bounty Tickets with this label rewards core contributors for completion label Jan 13, 2022
@andydotxyz
Copy link
Member

andydotxyz commented Feb 2, 2022

Proposal for the API (yes it is super simple, but fulfils what was agreed to add at this stage):

type desktop.App interface {
	SetSystemTrayMenu(*fyne.Menu)
}

Usage:

menu := fyne.NewMenu("Tray menu title", items...)
a := app.New()
if desk, ok := a.(desktop.App); ok {
	desk.SetSystemTrayMenu(menu)
}

Potentially we also need SetSystemTrayIcon(fyne.Resource) to support apps changing the icon and it would default to the app icon.

@stuartmscott
Copy link
Member

There are a few possibilities for implementing this in Android;

@andydotxyz andydotxyz self-assigned this Feb 3, 2022
@qwc
Copy link

qwc commented Feb 14, 2022

Hi,
I got the same usecase as mentioned above. I want to create a systray app (only Linux) which supports just a small menu, maybe a tooltip and notifications to be displayed.
Everything else, fyne has anyway. :)

Is there maybe already a prototype I could use for hacking?

I looked at systray already. But I took the restriction to have no other dependencies than Golang, and therefore I want to use fyne and fyne only.
TBH: I am currently in the research phase for the small systray app that I want for my already working service. The service is a nice MVP by itself, but having notifications for it would be the perfect fit and make the package complete. (https://qwc.github.io/backive/)

@andydotxyz
Copy link
Member

You can track development on feature/systray branch on my fork. We have added Windows and macOS support already.
I will open a PR once Linux is complete.

@qwc
Copy link

qwc commented Feb 16, 2022

Thank you for the effort! I think it will come just in time for the continuation of my project. :)

@riyalol
Copy link

riyalol commented Feb 17, 2022

Thanks for this excellent integration. I tried to give it a go (I know it is still WIP) for a little project that I am building.

With this piece of code:

mi := fyne.NewMenuItem("Login", func() {
	log.Println("System tray menu tapped")
})

if desk, ok := a.(desktop.App); ok {
	menu := fyne.NewMenu("Login", mi)
	desk.SetSystemTrayMenu(menu)
}

However, when I hit the "Login" button, the log message gets printed only once. After that, the "Login" menu does not seem to be active, and repeated presses don't invoke the callback (and hence do not print the log message). Any idea what might be the issue? Thanks in advance.

@andydotxyz
Copy link
Member

Thanks for the report @riyalol I will look into it as I develop the feature further.

@andydotxyz andydotxyz mentioned this issue Feb 28, 2022
6 tasks
@andydotxyz
Copy link
Member

That issue is resolved on the latest commit of the PR @riyalol :)

@qwc
Copy link

qwc commented Feb 28, 2022

but the library still needs work for Linux - working on it separately.

Damn, my current usecase is Linux only. Fingers crossed for easy solveable problems on Linux. * Impatiently waiting * ;)
My next project needs it for all OSs. ;)

@andydotxyz
Copy link
Member

Anything you know about dbus menus may help progress the Linux stuff quicker - it is a spaghetti of services and interfaces without documentation :(

@qwc
Copy link

qwc commented Feb 28, 2022

I as well do only know the basics. 😒
Not enough to use it for programming applications using it.

I could just find the dbus spec: https://dbus.freedesktop.org/doc/dbus-specification.html
Maybe d-feet helps in debugging: https://wiki.gnome.org/Apps/DFeet
Development repo: https://gitlab.freedesktop.org/dbus
Anything else should be on https://www.freedesktop.org/wiki/Software/dbus/

With dbus menus specifically i couldn't find anything additional, tbh. So nothing new to add. :( :( :'(

@andydotxyz
Copy link
Member

Landed in develop :)

Full Framework automation moved this from To do to Done Mar 10, 2022
@mvdelt
Copy link

mvdelt commented Apr 20, 2022

Proposal for the API (yes it is super simple, but fulfils what was agreed to add at this stage):

type desktop.App interface {
	SetSystemTrayMenu(*fyne.Menu)
}

Usage:

menu := fyne.NewMenu("Tray menu title", items...)
a := app.New()
if desk, ok := a.(desktop.App); ok {
	desk.SetSystemTrayMenu(menu)
}

Potentially we also need SetSystemTrayIcon(fyne.Resource) to support apps changing the icon and it would default to the app icon.

@andydotxyz Hi, thank you so much for developing these features.
I'm a newbie to Fyne. I just want to test the system tray. (and notification if it's possible.)
I searched quite a bit, but don't know what desktop.App is.
Do I need to go get fyne.io/fyne/v2@develop and import some different packages for the system tray?
If there is an example for system tray implementation, please let me know.
Dumb question but looking forward to your help. thanks! :)

P.S.1: I found github.com/fyne-io/systray,
but it's different than the above code you wrote. What should I use?

P.S.2: Yeah, this is not a place to talk about Go language itself,
but that code seems quite different from normal type assertion in Go.
Normally it's usually interface.(concrete_type), isn't it?
Thank you!

@andydotxyz
Copy link
Member

The code above is a type query - ok is true if the assertion is correct.
To get it working you need to add the import "fyne.io/fyne/v2/driver/desktop" sorry I missed that in the instructions.

Notifications work without anything special as they are on all platforms and are at App.SendNotification()

@mvdelt
Copy link

mvdelt commented Apr 20, 2022

The code above is a type query - ok is true if the assertion is correct. To get it working you need to add the import "fyne.io/fyne/v2/driver/desktop" sorry I missed that in the instructions.

Notifications work without anything special as they are on all platforms and are at App.SendNotification()

Thanks! works like a charm.

(Just for future reference, edited:)
There was a squiggly line in App in desktop.App, even though "fyne.io/fyne/v2/driver/desktop" was imported. The IDE (vscode) said "App not declared by package desktop". Previously I thought I imported a wrong package because of this. I couldn't go to the definition for desktop.App or desk.SetSystemTrayMenu.
But, interestingly, there was no problem with building and running, and the system tray worked well.
I restarted vscode several times but it didn't fix the squiggly line, but somehow suddenly it got fixed after I looked through the go.mod file. But I didn't modify anything... I think my system is not very stable(Win10 and vscode).

Anyways, now I can see the related definitions as well.
Thanks again :)

P.S. Solution: use 'replace' directive in go.mod file so that Go can resolve to the correct version of the package.
Just changing the fyne version in 'require' directive does not always make Go resolve to that version(I think it can happen if the version is pseudo-version number).
Researching on 'Go module' helps a lot: Go modules, go.mod file, and Managing dependencies.

@mei2015
Copy link

mei2015 commented Jun 2, 2022

why not to realese

@Jacalz
Copy link
Member

Jacalz commented Jun 2, 2022

why not to realese

This will be in the next release and it is releasing very soon.

@fayfive

This comment was marked as off-topic.

@Jacalz

This comment was marked as off-topic.

@paboum
Copy link

paboum commented Nov 24, 2022

Why is this KDE-dependent? Shouldn't you use the following?
https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/
example https://github.com/remko/go-sni

@andydotxyz
Copy link
Member

It isn't KDE specific - but all the panels we tested supported the kde notation but did not all support the FDO specification.
If you are aware of any panels that this does not work with please open an issue.

@fyne-io fyne-io deleted a comment from dosgo Dec 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bounty Tickets with this label rewards core contributors for completion future Features that might take a while to be sheduled Hacktoberfest
Projects
Development

No branches or pull requests