Move TrayMenu from config to runtime

Support better tray menu API
Move object creation to main thread
This commit is contained in:
Lea Anthony 2022-05-02 18:57:35 +10:00
commit ae0933c82a
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
12 changed files with 407 additions and 280 deletions

View file

@ -59,8 +59,9 @@ void UpdateApplicationMenu(void *inctx);
void SetMenuItemChecked(void* nsMenuItem, int checked);
/* Tray Menu */
void* NewNSStatusItem(const char* label);
void NewNSStatusItem(int);
void SetTrayMenu(void *nsStatusItem, void* nsMenu);
void SetTrayMenuLabel(void *nsStatusItem, const char *label);
void SetAbout(void *inctx, const char* title, const char* description, void* imagedata, int datalen);
void* AppendMenuItem(void* inctx, void* nsmenu, const char* label, const char* shortcutKey, int modifiers, int disabled, int checked, int menuItemID);
@ -69,4 +70,6 @@ void UpdateMenuItem(void* nsmenuitem, int checked);
NSString* safeInit(const char* input);
void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int template, int position);
#endif /* Application_h */

View file

@ -11,6 +11,7 @@
#import "AppDelegate.h"
#import "WailsMenu.h"
#import "WailsMenuItem.h"
#import "message.h"
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight) {
@ -274,12 +275,20 @@ void AppendRole(void *inctx, void *inMenu, int role) {
[menu appendRole :ctx :role];
}
void* NewNSStatusItem(const char* label) {
NSString *_label = safeInit(label);
NSStatusBar *statusBar = [NSStatusBar systemStatusBar];
NSStatusItem *result = [[statusBar statusItemWithLength:NSVariableStatusItemLength] retain];
[result button].title = _label;
return result;
void NewNSStatusItem(int id) {
ON_MAIN_THREAD(
NSStatusBar *statusBar = [NSStatusBar systemStatusBar];
NSStatusItem *result = [[statusBar statusItemWithLength:NSVariableStatusItemLength] retain];
objectCreated(id,result);
)
}
void SetTrayMenuLabel(void *_nsStatusItem, const char *label) {
ON_MAIN_THREAD(
NSStatusItem *nsStatusItem = (NSStatusItem*) _nsStatusItem;
nsStatusItem.button.title = safeInit(label);
free((void*)label);
)
}
void SetTrayMenu(void *nsStatusItem, void* nsMenu) {
@ -313,8 +322,8 @@ void SetAsApplicationMenu(void *inctx, void *inMenu) {
void UpdateApplicationMenu(void *inctx) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
ON_MAIN_THREAD(
NSApplication *app = [NSApplication sharedApplication];
[app setMainMenu:ctx.applicationMenu];
NSApplication *app = [NSApplication sharedApplication];
[app setMainMenu:ctx.applicationMenu];
)
}
@ -339,7 +348,7 @@ void UpdateMenuItem(void* nsmenuitem, int checked) {
ON_MAIN_THREAD(
WailsMenuItem *menuItem = (__bridge WailsMenuItem*) nsmenuitem;
[menuItem setState:(checked == 1?NSControlStateValueOn:NSControlStateValueOff)];
)
)
}
@ -348,6 +357,27 @@ void AppendSeparator(void* inMenu) {
[menu AppendSeparator];
}
void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int template, int position) {
ON_MAIN_THREAD(
NSStatusItem *statusItem = (NSStatusItem*) nsStatusItem;
NSData *nsdata = [NSData dataWithBytes:imageData length:imageDataLength];
NSImage *image = [[[NSImage alloc] initWithData:nsdata] autorelease];
if(template) {
image.template = true;
}
statusItem.button.image = image;
// Swap NSNoImage and NSImageLeading because we wanted NSImageLeading to be default in Go
int actualPosition = position;
if( position == 7) {
actualPosition = 0;
} else if (position == 0) {
actualPosition = 7;
}
[statusItem.button setImagePosition:actualPosition];
)
}
void Run(void *inctx, const char* url, int activationPolicy) {
WailsContext *ctx = (__bridge WailsContext*) inctx;
NSApplication *app = [NSApplication sharedApplication];

View file

@ -14,24 +14,82 @@ package darwin
*/
import "C"
import (
"sync"
"unsafe"
"github.com/google/uuid"
"github.com/wailsapp/wails/v2/pkg/menu"
"github.com/wailsapp/wails/v2/pkg/menu/keys"
)
var createNSObjectMap = make(map[uint32]chan unsafe.Pointer)
var createNSObjectMapLock sync.RWMutex
func waitNSObjectCreate(id uint32, fn func()) unsafe.Pointer {
waitchan := make(chan unsafe.Pointer)
createNSObjectMapLock.Lock()
createNSObjectMap[id] = waitchan
createNSObjectMapLock.Unlock()
fn()
result := <-waitchan
createNSObjectMapLock.Lock()
createNSObjectMap[id] = nil
createNSObjectMapLock.Unlock()
return result
}
//export objectCreated
func objectCreated(id uint32, pointer unsafe.Pointer) {
createNSObjectMapLock.Lock()
createNSObjectMap[id] <- pointer
createNSObjectMapLock.Unlock()
}
func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu) *NSTrayMenu {
c := NewCalloc()
defer c.Free()
theMenu := NewNSMenu(context, "")
processMenu(theMenu, trayMenu.Menu)
title := c.String(trayMenu.Label)
nsStatusItem := C.NewNSStatusItem(title)
C.SetTrayMenu(nsStatusItem, theMenu.nsmenu)
return &NSTrayMenu{
id := uuid.New().ID()
nsStatusItem := waitNSObjectCreate(id, func() {
C.NewNSStatusItem(C.int(id))
})
result := &NSTrayMenu{
context: context,
nsStatusItem: nsStatusItem,
}
if trayMenu.Label != "" {
result.SetLabel(trayMenu.Label)
}
// TODO: Move this into NSTrayMenu method
if trayMenu.Menu != nil {
theMenu := NewNSMenu(context, "")
processMenu(theMenu, trayMenu.Menu)
result.SetMenu(theMenu)
}
if trayMenu.Image != nil {
result.SetImage(trayMenu.Image)
}
return result
}
func (n *NSTrayMenu) SetImage(image *menu.TrayImage) {
if image.Image == nil {
return
}
C.SetTrayImage(n.nsStatusItem,
unsafe.Pointer(&image.Image[0]),
C.int(len(image.Image)),
bool2Cint(image.IsTemplate),
C.int(image.Position),
)
}
func (n *NSTrayMenu) SetMenu(menu *NSMenu) {
C.SetTrayMenu(n.nsStatusItem, menu.nsmenu)
}
type NSMenu struct {

View file

@ -21,6 +21,7 @@ void processOpenFileDialogResponse(const char*);
void processSaveFileDialogResponse(const char*);
void processCallback(int);
void processNotification(int);
void objectCreated(int, void*);
#ifdef __cplusplus
}

View file

@ -9,7 +9,6 @@ package darwin
#include <stdlib.h>
*/
import "C"
import (
"unsafe"
@ -17,13 +16,10 @@ import (
"github.com/wailsapp/wails/v2/pkg/menu"
)
func (f *Frontend) TrayMenuAdd(trayMenu *menu.TrayMenu) {
if f.applicationDidFinishLaunching == false {
f.trayMenusBuffer = append(f.trayMenusBuffer, trayMenu)
return
}
func (f *Frontend) TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl {
nsTrayMenu := f.mainWindow.TrayMenuAdd(trayMenu)
f.trayMenus[trayMenu] = nsTrayMenu
return nsTrayMenu
}
type NSTrayMenu struct {
@ -31,6 +27,11 @@ type NSTrayMenu struct {
nsStatusItem unsafe.Pointer // NSStatusItem
}
func (n *NSTrayMenu) SetLabel(label string) {
cLabel := C.CString(label)
C.SetTrayMenuLabel(n.nsStatusItem, cLabel)
}
func (w *Window) TrayMenuAdd(trayMenu *menu.TrayMenu) *NSTrayMenu {
return NewNSTrayMenu(w.context, trayMenu)
}

View file

@ -112,10 +112,6 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
result.SetApplicationMenu(frontendOptions.Menu)
}
if frontendOptions.TrayMenu != nil {
result.TrayMenuAdd(frontendOptions.TrayMenu)
}
return result
}

View file

@ -103,5 +103,5 @@ type Frontend interface {
BrowserOpenURL(url string)
// Tray Menu
TrayMenuAdd(trayMenu *menu.TrayMenu)
TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl
}

View file

@ -1,12 +1,15 @@
package menumanager
import (
"encoding/json"
"fmt"
"github.com/wailsapp/wails/v2/pkg/menu"
)
import "github.com/wailsapp/wails/v2/pkg/menu"
//
//import (
// "encoding/json"
// "fmt"
//
// "github.com/wailsapp/wails/v2/pkg/menu"
//)
//
type ContextMenu struct {
ID string
ProcessedMenu *WailsMenu
@ -14,48 +17,49 @@ type ContextMenu struct {
menu *menu.Menu
}
func (t *ContextMenu) AsJSON() (string, error) {
data, err := json.Marshal(t)
if err != nil {
return "", err
}
return string(data), nil
}
func NewContextMenu(contextMenu *menu.ContextMenu) *ContextMenu {
result := &ContextMenu{
ID: contextMenu.ID,
menu: contextMenu.Menu,
menuItemMap: NewMenuItemMap(),
}
result.menuItemMap.AddMenu(contextMenu.Menu)
result.ProcessedMenu = NewWailsMenu(result.menuItemMap, result.menu)
return result
}
func (m *Manager) AddContextMenu(contextMenu *menu.ContextMenu) {
newContextMenu := NewContextMenu(contextMenu)
// Save the references
m.contextMenus[contextMenu.ID] = newContextMenu
m.contextMenuPointers[contextMenu] = contextMenu.ID
}
func (m *Manager) UpdateContextMenu(contextMenu *menu.ContextMenu) (string, error) {
contextMenuID, contextMenuKnown := m.contextMenuPointers[contextMenu]
if !contextMenuKnown {
return "", fmt.Errorf("unknown Context Menu '%s'. Please add the context menu using AddContextMenu()", contextMenu.ID)
}
// Create the updated context menu
updatedContextMenu := NewContextMenu(contextMenu)
// Save the reference
m.contextMenus[contextMenuID] = updatedContextMenu
return updatedContextMenu.AsJSON()
}
//
//func (t *ContextMenu) AsJSON() (string, error) {
// data, err := json.Marshal(t)
// if err != nil {
// return "", err
// }
// return string(data), nil
//}
//
//func NewContextMenu(contextMenu *menu.ContextMenu) *ContextMenu {
//
// result := &ContextMenu{
// ID: contextMenu.ID,
// menu: contextMenu.Menu,
// menuItemMap: NewMenuItemMap(),
// }
//
// result.menuItemMap.AddMenu(contextMenu.Menu)
// result.ProcessedMenu = NewWailsMenu(result.menuItemMap, result.menu)
//
// return result
//}
//
//func (m *Manager) AddContextMenu(contextMenu *menu.ContextMenu) {
//
// newContextMenu := NewContextMenu(contextMenu)
//
// // Save the references
// m.contextMenus[contextMenu.ID] = newContextMenu
// m.contextMenuPointers[contextMenu] = contextMenu.ID
//}
//
//func (m *Manager) UpdateContextMenu(contextMenu *menu.ContextMenu) (string, error) {
// contextMenuID, contextMenuKnown := m.contextMenuPointers[contextMenu]
// if !contextMenuKnown {
// return "", fmt.Errorf("unknown Context Menu '%s'. Please add the context menu using AddContextMenu()", contextMenu.ID)
// }
//
// // Create the updated context menu
// updatedContextMenu := NewContextMenu(contextMenu)
//
// // Save the reference
// m.contextMenus[contextMenuID] = updatedContextMenu
//
// return updatedContextMenu.AsJSON()
//}

View file

@ -2,6 +2,7 @@ package menumanager
import (
"fmt"
"github.com/wailsapp/wails/v2/pkg/menu"
)

View file

@ -1,15 +1,11 @@
package menumanager
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"sync"
"github.com/leaanthony/go-ansi-parser"
"github.com/pkg/errors"
"github.com/wailsapp/wails/v2/pkg/menu"
)
@ -32,7 +28,7 @@ type TrayMenu struct {
FontName string
Disabled bool
Tooltip string `json:",omitempty"`
Image string
Image []byte
MacTemplateImage bool
RGBA string
menuItemMap *MenuItemMap
@ -42,181 +38,182 @@ type TrayMenu struct {
StyledLabel []*ansi.StyledText `json:",omitempty"`
}
func (t *TrayMenu) AsJSON() (string, error) {
data, err := json.Marshal(t)
if err != nil {
return "", err
}
return string(data), nil
}
func NewTrayMenu(trayMenu *menu.TrayMenu) *TrayMenu {
// Parse ANSI text
var styledLabel []*ansi.StyledText
tempLabel := trayMenu.Label
if strings.Contains(tempLabel, "\033[") {
parsedLabel, err := ansi.Parse(tempLabel)
if err == nil {
styledLabel = parsedLabel
}
}
result := &TrayMenu{
Label: trayMenu.Label,
FontName: trayMenu.FontName,
FontSize: trayMenu.FontSize,
Disabled: trayMenu.Disabled,
Tooltip: trayMenu.Tooltip,
Image: trayMenu.Image,
MacTemplateImage: trayMenu.MacTemplateImage,
menu: trayMenu.Menu,
RGBA: trayMenu.RGBA,
menuItemMap: NewMenuItemMap(),
trayMenu: trayMenu,
StyledLabel: styledLabel,
}
result.menuItemMap.AddMenu(trayMenu.Menu)
result.ProcessedMenu = NewWailsMenu(result.menuItemMap, result.menu)
return result
}
func (m *Manager) OnTrayMenuOpen(id string) {
trayMenu, ok := m.trayMenus[id]
if !ok {
return
}
if trayMenu.trayMenu.OnOpen == nil {
return
}
go trayMenu.trayMenu.OnOpen()
}
func (m *Manager) OnTrayMenuClose(id string) {
trayMenu, ok := m.trayMenus[id]
if !ok {
return
}
if trayMenu.trayMenu.OnClose == nil {
return
}
go trayMenu.trayMenu.OnClose()
}
func (m *Manager) AddTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
newTrayMenu := NewTrayMenu(trayMenu)
// Hook up a new ID
trayID := generateTrayID()
newTrayMenu.ID = trayID
// Save the references
m.trayMenus[trayID] = newTrayMenu
m.trayMenuPointers[trayMenu] = trayID
return newTrayMenu.AsJSON()
}
func (m *Manager) GetTrayID(trayMenu *menu.TrayMenu) (string, error) {
trayID, exists := m.trayMenuPointers[trayMenu]
if !exists {
return "", fmt.Errorf("Unable to find menu ID for tray menu!")
}
return trayID, nil
}
// SetTrayMenu updates or creates a menu
func (m *Manager) SetTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
trayID, trayMenuKnown := m.trayMenuPointers[trayMenu]
if !trayMenuKnown {
return m.AddTrayMenu(trayMenu)
}
// Create the updated tray menu
updatedTrayMenu := NewTrayMenu(trayMenu)
updatedTrayMenu.ID = trayID
// Save the reference
m.trayMenus[trayID] = updatedTrayMenu
return updatedTrayMenu.AsJSON()
}
func (m *Manager) GetTrayMenus() ([]string, error) {
result := []string{}
for _, trayMenu := range m.trayMenus {
JSON, err := trayMenu.AsJSON()
if err != nil {
return nil, err
}
result = append(result, JSON)
}
return result, nil
}
func (m *Manager) UpdateTrayMenuLabel(trayMenu *menu.TrayMenu) (string, error) {
trayID, trayMenuKnown := m.trayMenuPointers[trayMenu]
if !trayMenuKnown {
return "", fmt.Errorf("[UpdateTrayMenuLabel] unknown tray id for tray %s", trayMenu.Label)
}
type LabelUpdate struct {
ID string
Label string `json:",omitempty"`
FontName string `json:",omitempty"`
FontSize int
RGBA string `json:",omitempty"`
Disabled bool
Tooltip string `json:",omitempty"`
Image string `json:",omitempty"`
MacTemplateImage bool
StyledLabel []*ansi.StyledText `json:",omitempty"`
}
// Parse ANSI text
var styledLabel []*ansi.StyledText
tempLabel := trayMenu.Label
if strings.Contains(tempLabel, "\033[") {
parsedLabel, err := ansi.Parse(tempLabel)
if err == nil {
styledLabel = parsedLabel
}
}
update := &LabelUpdate{
ID: trayID,
Label: trayMenu.Label,
FontName: trayMenu.FontName,
FontSize: trayMenu.FontSize,
Disabled: trayMenu.Disabled,
Tooltip: trayMenu.Tooltip,
Image: trayMenu.Image,
MacTemplateImage: trayMenu.MacTemplateImage,
RGBA: trayMenu.RGBA,
StyledLabel: styledLabel,
}
data, err := json.Marshal(update)
if err != nil {
return "", errors.Wrap(err, "[UpdateTrayMenuLabel] ")
}
return string(data), nil
}
func (m *Manager) GetContextMenus() ([]string, error) {
result := []string{}
for _, contextMenu := range m.contextMenus {
JSON, err := contextMenu.AsJSON()
if err != nil {
return nil, err
}
result = append(result, JSON)
}
return result, nil
}
//
//func (t *TrayMenu) AsJSON() (string, error) {
// data, err := json.Marshal(t)
// if err != nil {
// return "", err
// }
// return string(data), nil
//}
//
//func NewTrayMenu(trayMenu *menu.TrayMenu) *TrayMenu {
//
// // Parse ANSI text
// var styledLabel []*ansi.StyledText
// tempLabel := trayMenu.Label
// if strings.Contains(tempLabel, "\033[") {
// parsedLabel, err := ansi.Parse(tempLabel)
// if err == nil {
// styledLabel = parsedLabel
// }
// }
//
// result := &TrayMenu{
// Label: trayMenu.Label,
// FontName: trayMenu.FontName,
// FontSize: trayMenu.FontSize,
// Disabled: trayMenu.Disabled,
// Tooltip: trayMenu.Tooltip,
// Image: trayMenu.Image,
// MacTemplateImage: trayMenu.MacTemplateImage,
// menu: trayMenu.Menu,
// RGBA: trayMenu.RGBA,
// menuItemMap: NewMenuItemMap(),
// trayMenu: trayMenu,
// StyledLabel: styledLabel,
// }
//
// result.menuItemMap.AddMenu(trayMenu.Menu)
// result.ProcessedMenu = NewWailsMenu(result.menuItemMap, result.menu)
//
// return result
//}
//
//func (m *Manager) OnTrayMenuOpen(id string) {
// trayMenu, ok := m.trayMenus[id]
// if !ok {
// return
// }
// if trayMenu.trayMenu.OnOpen == nil {
// return
// }
// go trayMenu.trayMenu.OnOpen()
//}
//
//func (m *Manager) OnTrayMenuClose(id string) {
// trayMenu, ok := m.trayMenus[id]
// if !ok {
// return
// }
// if trayMenu.trayMenu.OnClose == nil {
// return
// }
// go trayMenu.trayMenu.OnClose()
//}
//
//func (m *Manager) AddTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
// newTrayMenu := NewTrayMenu(trayMenu)
//
// // Hook up a new ID
// trayID := generateTrayID()
// newTrayMenu.ID = trayID
//
// // Save the references
// m.trayMenus[trayID] = newTrayMenu
// m.trayMenuPointers[trayMenu] = trayID
//
// return newTrayMenu.AsJSON()
//}
//
//func (m *Manager) GetTrayID(trayMenu *menu.TrayMenu) (string, error) {
// trayID, exists := m.trayMenuPointers[trayMenu]
// if !exists {
// return "", fmt.Errorf("Unable to find menu ID for tray menu!")
// }
// return trayID, nil
//}
//
//// SetTrayMenu updates or creates a menu
//func (m *Manager) SetTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
// trayID, trayMenuKnown := m.trayMenuPointers[trayMenu]
// if !trayMenuKnown {
// return m.AddTrayMenu(trayMenu)
// }
//
// // Create the updated tray menu
// updatedTrayMenu := NewTrayMenu(trayMenu)
// updatedTrayMenu.ID = trayID
//
// // Save the reference
// m.trayMenus[trayID] = updatedTrayMenu
//
// return updatedTrayMenu.AsJSON()
//}
//
//func (m *Manager) GetTrayMenus() ([]string, error) {
// result := []string{}
// for _, trayMenu := range m.trayMenus {
// JSON, err := trayMenu.AsJSON()
// if err != nil {
// return nil, err
// }
// result = append(result, JSON)
// }
//
// return result, nil
//}
//
//func (m *Manager) UpdateTrayMenuLabel(trayMenu *menu.TrayMenu) (string, error) {
// trayID, trayMenuKnown := m.trayMenuPointers[trayMenu]
// if !trayMenuKnown {
// return "", fmt.Errorf("[UpdateTrayMenuLabel] unknown tray id for tray %s", trayMenu.Label)
// }
//
// type LabelUpdate struct {
// ID string
// Label string `json:",omitempty"`
// FontName string `json:",omitempty"`
// FontSize int
// RGBA string `json:",omitempty"`
// Disabled bool
// Tooltip string `json:",omitempty"`
// Image []byte `json:",omitempty"`
// MacTemplateImage bool
// StyledLabel []*ansi.StyledText `json:",omitempty"`
// }
//
// // Parse ANSI text
// var styledLabel []*ansi.StyledText
// tempLabel := trayMenu.Label
// if strings.Contains(tempLabel, "\033[") {
// parsedLabel, err := ansi.Parse(tempLabel)
// if err == nil {
// styledLabel = parsedLabel
// }
// }
//
// update := &LabelUpdate{
// ID: trayID,
// Label: trayMenu.Label,
// FontName: trayMenu.FontName,
// FontSize: trayMenu.FontSize,
// Disabled: trayMenu.Disabled,
// Tooltip: trayMenu.Tooltip,
// Image: trayMenu.Image,
// MacTemplateImage: trayMenu.MacTemplateImage,
// RGBA: trayMenu.RGBA,
// StyledLabel: styledLabel,
// }
//
// data, err := json.Marshal(update)
// if err != nil {
// return "", errors.Wrap(err, "[UpdateTrayMenuLabel] ")
// }
//
// return string(data), nil
//
//}
//
//func (m *Manager) GetContextMenus() ([]string, error) {
// result := []string{}
// for _, contextMenu := range m.contextMenus {
// JSON, err := contextMenu.AsJSON()
// if err != nil {
// return nil, err
// }
// result = append(result, JSON)
// }
//
// return result, nil
//}

View file

@ -7,7 +7,32 @@ import (
)
type TrayMenuAdd interface {
TrayMenuAdd(menu *TrayMenu)
TrayMenuAdd(menu *TrayMenu) TrayMenuImpl
}
type TrayMenuImpl interface {
SetLabel(string)
SetImage(*TrayImage)
}
type ImagePosition int
const (
NSImageLeading ImagePosition = 0
NSImageOnly ImagePosition = 1
NSImageLeft ImagePosition = 2
NSImageRight ImagePosition = 3
NSImageBelow ImagePosition = 4
NSImageAbove ImagePosition = 5
NSImageOverlaps ImagePosition = 6
NSNoImage ImagePosition = 7
NSImageTrailing ImagePosition = 8
)
type TrayImage struct {
Image []byte
IsTemplate bool
Position ImagePosition
}
// TrayMenu are the options
@ -17,12 +42,7 @@ type TrayMenu struct {
// Label is the text we wish to display in the tray
Label string
// Image is the name of the tray icon we wish to display.
// These are read up during build from <projectdir>/trayicons and
// the filenames are used as IDs, minus the extension
// EG: <projectdir>/trayicons/main.png can be referenced here with "main"
// If the image is not a filename, it will be treated as base64 image data
Image string
Image *TrayImage
// MacTemplateImage indicates that on a Mac, this image is a template image
MacTemplateImage bool
@ -51,22 +71,39 @@ type TrayMenu struct {
// OnClose is called when the Menu is closed
OnClose func()
impl TrayMenuImpl
}
func NewTrayMenu(ctx context.Context) *TrayMenu {
return &TrayMenu{
ctx: ctx,
func NewTrayMenu() *TrayMenu {
return &TrayMenu{}
}
func (t *TrayMenu) Show(ctx context.Context) {
if ctx == nil {
log.Fatal("TrayMenu.Show() called before Run()")
}
}
func (t *TrayMenu) Show() {
result := t.ctx.Value("frontend")
t.ctx = ctx
result := ctx.Value("frontend")
if result == nil {
pc, _, _, _ := goruntime.Caller(1)
funcName := goruntime.FuncForPC(pc).Name()
log.Fatalf("invalid context at '%s'", funcName)
}
println("\n\n\n\nFWEFWEFWFE")
result.(TrayMenuAdd).TrayMenuAdd(t)
t.impl = result.(TrayMenuAdd).TrayMenuAdd(t)
}
func (t *TrayMenu) SetLabel(label string) {
t.Label = label
if t.impl != nil {
t.impl.SetLabel(label)
}
}
func (t *TrayMenu) SetImage(image *TrayImage) {
t.Image = image
if t.impl != nil {
t.impl.SetImage(image)
}
}

View file

@ -56,10 +56,9 @@ type App struct {
//ContextMenus []*menu.ContextMenu
//TrayMenus []*menu.TrayMenu
Windows *windows.Options
Mac *mac.Options
Linux *linux.Options
TrayMenu *menu.TrayMenu
Windows *windows.Options
Mac *mac.Options
Linux *linux.Options
}
type RGBA struct {