mirror of
https://github.com/netbirdio/systray.git
synced 2026-05-22 17:08:41 -07:00
refactor to break Run into register and native loop
This commit is contained in:
+2
-22
@@ -6,8 +6,6 @@ import (
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/lxn/walk"
|
||||
|
||||
"github.com/getlantern/systray"
|
||||
"github.com/getlantern/systray/example/icon"
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
@@ -25,26 +23,8 @@ func main() {
|
||||
}
|
||||
|
||||
if *webview {
|
||||
systray.Register(onExit)
|
||||
onReady()
|
||||
mainWindow, err := walk.NewMainWindow()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to create main window: %v\n", err))
|
||||
}
|
||||
mainWindow.SetTitle("Webview")
|
||||
mainWindow.SetWidth(800)
|
||||
mainWindow.SetHeight(600)
|
||||
layout := walk.NewVBoxLayout()
|
||||
if err := mainWindow.SetLayout(layout); err != nil {
|
||||
panic(fmt.Sprintf("Failed to set layout: %v\n", err))
|
||||
}
|
||||
webView, err := walk.NewWebView(mainWindow)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to create webview window: %v\n", err))
|
||||
}
|
||||
webView.SetURL("https://www.getlantern.org")
|
||||
mainWindow.SetVisible(true)
|
||||
mainWindow.Run()
|
||||
systray.Register(onReady, onExit)
|
||||
showWebviewOnWindows()
|
||||
} else {
|
||||
systray.Run(onReady, onExit)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
//+build !windows
|
||||
|
||||
package main
|
||||
|
||||
func showWebviewOnWindows() {
|
||||
panic("not implemented")
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/lxn/walk"
|
||||
)
|
||||
|
||||
func showWebviewOnWindows() {
|
||||
mainWindow, err := walk.NewMainWindow()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to create main window: %v\n", err))
|
||||
}
|
||||
mainWindow.SetTitle("Webview")
|
||||
mainWindow.SetWidth(800)
|
||||
mainWindow.SetHeight(600)
|
||||
layout := walk.NewVBoxLayout()
|
||||
if err := mainWindow.SetLayout(layout); err != nil {
|
||||
panic(fmt.Sprintf("Failed to set layout: %v\n", err))
|
||||
}
|
||||
webView, err := walk.NewWebView(mainWindow)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to create webview window: %v\n", err))
|
||||
}
|
||||
webView.SetURL("https://www.getlantern.org")
|
||||
mainWindow.SetVisible(true)
|
||||
mainWindow.Run()
|
||||
}
|
||||
+24
-44
@@ -1,8 +1,5 @@
|
||||
/*
|
||||
Package systray is a cross-platform Go library to place an icon and menu in the notification area.
|
||||
|
||||
Methods can be called from any goroutine except Run(), which should be called
|
||||
at the very beginning of main() to lock at main thread.
|
||||
*/
|
||||
package systray
|
||||
|
||||
@@ -16,11 +13,22 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
hasStarted = int64(0)
|
||||
hasQuit = int64(0)
|
||||
log = golog.LoggerFor("systray")
|
||||
|
||||
systrayReady func()
|
||||
systrayExit func()
|
||||
menuItems = make(map[int32]*MenuItem)
|
||||
menuItemsLock sync.RWMutex
|
||||
|
||||
currentID = int32(-1)
|
||||
quitOnce sync.Once
|
||||
)
|
||||
|
||||
// MenuItem is used to keep track each menu item of systray
|
||||
func init() {
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
|
||||
// MenuItem is used to keep track each menu item of systray.
|
||||
// Don't create it directly, use the one systray.AddMenuItem() returned
|
||||
type MenuItem struct {
|
||||
// ClickedCh is the channel which will be notified when the menu item is clicked
|
||||
@@ -60,25 +68,17 @@ func newMenuItem(title string, tooltip string, parent *MenuItem) *MenuItem {
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
log = golog.LoggerFor("systray")
|
||||
|
||||
systrayReady func()
|
||||
systrayExit func()
|
||||
menuItems = make(map[int32]*MenuItem)
|
||||
menuItemsLock sync.RWMutex
|
||||
|
||||
currentID = int32(-1)
|
||||
)
|
||||
|
||||
// Run initializes GUI and starts the event loop, then invokes the onReady
|
||||
// callback.
|
||||
// It blocks until systray.Quit() is called.
|
||||
// Should be called at the very beginning of main() to lock at main thread.
|
||||
// callback. It blocks until systray.Quit() is called.
|
||||
func Run(onReady func(), onExit func()) {
|
||||
runtime.LockOSThread()
|
||||
atomic.StoreInt64(&hasStarted, 1)
|
||||
Register(onReady, onExit)
|
||||
nativeLoop()
|
||||
}
|
||||
|
||||
// Register initializes GUI and registers the callbacks but relies on the
|
||||
// caller to run the event loop somewhere else. It's useful if the program
|
||||
// needs to show other UI elements, for example, webview.
|
||||
func Register(onReady func(), onExit func()) {
|
||||
if onReady == nil {
|
||||
systrayReady = func() {}
|
||||
} else {
|
||||
@@ -92,38 +92,18 @@ func Run(onReady func(), onExit func()) {
|
||||
close(readyCh)
|
||||
}
|
||||
}
|
||||
|
||||
// unlike onReady, onExit runs in the event loop to make sure it has time to
|
||||
// finish before the process terminates
|
||||
if onExit == nil {
|
||||
onExit = func() {}
|
||||
}
|
||||
systrayExit = onExit
|
||||
|
||||
nativeLoop()
|
||||
}
|
||||
|
||||
func Register(onExit func()) {
|
||||
runtime.LockOSThread()
|
||||
atomic.StoreInt64(&hasStarted, 1)
|
||||
// unlike onReady, onExit runs in the event loop to make sure it has time to
|
||||
// finish before the process terminates
|
||||
if onExit == nil {
|
||||
onExit = func() {}
|
||||
}
|
||||
systrayExit = onExit
|
||||
register()
|
||||
}
|
||||
|
||||
func Run2() {
|
||||
run()
|
||||
registerSystray()
|
||||
}
|
||||
|
||||
// Quit the systray
|
||||
func Quit() {
|
||||
if atomic.LoadInt64(&hasStarted) == 1 && atomic.CompareAndSwapInt64(&hasQuit, 0, 1) {
|
||||
quit()
|
||||
}
|
||||
quitOnce.Do(quit)
|
||||
}
|
||||
|
||||
// AddMenuItem adds a menu item with the designated title and tooltip.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
extern void systray_ready();
|
||||
extern void systray_on_exit();
|
||||
extern void systray_menu_item_selected(int menu_id);
|
||||
void registerSystray(void);
|
||||
int nativeLoop(void);
|
||||
|
||||
void setIcon(const char* iconBytes, int length, bool template);
|
||||
|
||||
+4
-1
@@ -209,9 +209,12 @@ NSMenuItem *find_menu_item(NSMenu *ourMenu, NSNumber *menuId) {
|
||||
|
||||
@end
|
||||
|
||||
int nativeLoop(void) {
|
||||
void registerSystray(void) {
|
||||
AppDelegate *delegate = [[AppDelegate alloc] init];
|
||||
[[NSApplication sharedApplication] setDelegate:delegate];
|
||||
}
|
||||
|
||||
int nativeLoop(void) {
|
||||
[NSApp run];
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
+4
-1
@@ -23,7 +23,7 @@ typedef struct {
|
||||
short checked;
|
||||
} MenuItemInfo;
|
||||
|
||||
int nativeLoop(void) {
|
||||
void registerSystray(void) {
|
||||
gtk_init(0, NULL);
|
||||
global_app_indicator = app_indicator_new("systray", "",
|
||||
APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
|
||||
@@ -31,6 +31,9 @@ int nativeLoop(void) {
|
||||
global_tray_menu = gtk_menu_new();
|
||||
app_indicator_set_menu(global_app_indicator, GTK_MENU(global_tray_menu));
|
||||
systray_ready();
|
||||
}
|
||||
|
||||
int nativeLoop(void) {
|
||||
gtk_main();
|
||||
systray_on_exit();
|
||||
return 0;
|
||||
|
||||
@@ -15,6 +15,10 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func registerSystray() {
|
||||
C.registerSystray()
|
||||
}
|
||||
|
||||
func nativeLoop() {
|
||||
C.nativeLoop()
|
||||
}
|
||||
|
||||
+9
-12
@@ -236,14 +236,17 @@ var wt winTray
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx
|
||||
func (t *winTray) wndProc(hWnd windows.Handle, message uint32, wParam, lParam uintptr) (lResult uintptr) {
|
||||
const (
|
||||
WM_COMMAND = 0x0111
|
||||
WM_DESTROY = 0x0002
|
||||
WM_CLOSE = 0x0010
|
||||
WM_ENDSESSION = 0x16
|
||||
WM_RBUTTONUP = 0x0205
|
||||
WM_LBUTTONUP = 0x0202
|
||||
WM_COMMAND = 0x0111
|
||||
WM_ENDSESSION = 0x0016
|
||||
WM_CLOSE = 0x0010
|
||||
WM_DESTROY = 0x0002
|
||||
WM_CREATE = 0x0001
|
||||
)
|
||||
switch message {
|
||||
case WM_CREATE:
|
||||
systrayReady()
|
||||
case WM_COMMAND:
|
||||
menuItemId := int32(wParam)
|
||||
// https://docs.microsoft.com/en-us/windows/win32/menurc/wm-command#menus
|
||||
@@ -712,13 +715,7 @@ func (t *winTray) iconToBitmap(hIcon windows.Handle) (windows.Handle, error) {
|
||||
return windows.Handle(hMemBmp), nil
|
||||
}
|
||||
|
||||
func nativeLoop() {
|
||||
register()
|
||||
go systrayReady()
|
||||
run()
|
||||
}
|
||||
|
||||
func register() {
|
||||
func registerSystray() {
|
||||
if err := wt.initInstance(); err != nil {
|
||||
log.Errorf("Unable to init instance: %v", err)
|
||||
return
|
||||
@@ -731,7 +728,7 @@ func register() {
|
||||
|
||||
}
|
||||
|
||||
func run() {
|
||||
func nativeLoop() {
|
||||
// Main message pump.
|
||||
m := &struct {
|
||||
WindowHandle windows.Handle
|
||||
|
||||
Reference in New Issue
Block a user