refactor to break Run into register and native loop

This commit is contained in:
Joesis
2020-05-11 00:17:43 -07:00
parent a05d1b4d22
commit 40effd0609
9 changed files with 82 additions and 80 deletions
+2 -22
View File
@@ -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)
}
+7
View File
@@ -0,0 +1,7 @@
//+build !windows
package main
func showWebviewOnWindows() {
panic("not implemented")
}
+27
View File
@@ -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
View File
@@ -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.
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+4
View File
@@ -15,6 +15,10 @@ import (
"unsafe"
)
func registerSystray() {
C.registerSystray()
}
func nativeLoop() {
C.nativeLoop()
}
+9 -12
View File
@@ -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