英文:
Can somebody give some inputs on how to debug to understand the behaviour of below golang snippet on macOS and linux?
问题
package main
import (
"fmt"
"io/ioutil"
"github.com/getlantern/systray"
)
func main() {
fmt.Println("main started")
systray.Run(onReady, onExit)
fmt.Println("back to main")
}
func onReady() {
icoFile := "sample.ico"
icon, err := ioutil.ReadFile(icoFile)
if err != nil {
fmt.Println("err =", err)
}
systray.SetIcon(icon)
systray.SetTitle("Awesome App")
systray.SetTooltip("Pretty awesome超级棒")
mQuit := systray.AddMenuItem("Quit", "Quit the whole app")
go func() {
for {
select {
case <-mQuit.ClickedCh:
fmt.Println("Quit Systray")
systray.Quit()
}
}
}()
}
func onExit() {
// clean up here
}
我使用上面的代码片段在Mac和Linux上启动了systray。
当从菜单选项中选择退出时,在两个平台上的行为不同。
在Linux(以及Windows)中,在退出systray后,控制权返回到main函数并打印"back to main",而在macOS中,这个日志不会出现,这意味着应用程序从systray.Run函数退出(控制权没有返回到main函数)。
最初我认为这可能是getlantern/systray的问题。当我深入研究代码时,我发现Linux和macOS的代码是相同的。因此,我认为这种行为的原因可能是操作系统。
我正在寻找一些指针来分析这个问题。如果有任何已知的资源可以理解这个问题,那将是很大的帮助。
英文:
package main
import (
"fmt"
"io/ioutil"
"github.com/getlantern/systray"
)
func main() {
fmt.Println("main started")
systray.Run(onReady, onExit)
fmt.Println("back to main")
}
func onReady() {
icoFile := "sample.ico"
icon, err := ioutil.ReadFile(icoFile)
if err != nil {
fmt.Println("err =", err)
}
systray.SetIcon(icon)
systray.SetTitle("Awesome App")
systray.SetTooltip("Pretty awesome超级棒")
mQuit := systray.AddMenuItem("Quit", "Quit the whole app")
go func() {
for {
select {
case <-mQuit.ClickedCh:
fmt.Println("Quit Systray")
systray.Quit()
}
}
}()
}
func onExit() {
// clean up here
}
I lanuched the systray using above snippet in both mac and linux.
When quit is selected from the menu options, it behaves differently on both the platforms.
In linux(also in windows), after the systray is quit, control get backs to main and prints "back to main" whereas in macOS, this log is not occuring which means that the application exits from systray.Run function(control is not getting back to the main function).
Initially I thought that this could be the problem of getlantern/systray. When I dived deeper into the code, I found that the code is same for linux as well as macOS. Hence I am thinking that, the cause of this behaviour could be with OS.
I am looking for some pointer to analyse this issue. If there is any known source to understand this, it would be great help as well.
答案1
得分: 2
实际上,这个库中有一个区别。Quit
方法会调用内部的 quit
函数。在 Linux 上,quit
隐藏通知器并调用 gtk_main_quit
来结束 GTK+ 主循环,这将导致 Run
方法返回。在 Windows 上,quit
发送一个 WM_CLOSE
消息给应用程序,关闭系统托盘的“窗口”,最终也会导致事件循环退出。在 macOS 上,quit
调用应用程序的 terminate 方法,该方法进行一些清理操作,然后退出进程。甚至苹果的文档中都说:
> 不要在应用程序的 main()
函数中放置最终的清理代码,因为它永远不会被执行。
我不是 macOS 的专家,但我认为为了一致性,systray 库应该调用 stop 而不是 terminate —— 你可能想要提交一个错误报告来提出这个问题。
英文:
There is in fact a difference in the library. The Quit
method causes the internal quit
function to be called. On Linux, quit
hides the notifier and calls gtk_main_quit
to end the GTK+ mainloop, which will cause Run
to return. On Windows, quit
sends a WM_CLOSE
message to the app, which closes the systray "window" and eventually also causes the event loop to exit. On macOS, quit
calls the terminate method on the app, which does some cleanup and then exits the process. The Apple documentation even says:
> Don't bother to put final cleanup code in your app's main()
function—it will never be executed.
I'm not a mac expert but it seems to me that for consistency, the systray library should call stop instead of terminate — you may want to file a bug asking for that.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论