mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 22:55:48 +01:00
Refactor, tidy up and trim the fat!
This commit is contained in:
parent
3f53e8fd5f
commit
583153383a
18 changed files with 276 additions and 143 deletions
|
|
@ -34,7 +34,7 @@ type Application struct {
|
|||
memory []unsafe.Pointer
|
||||
|
||||
// This is the main app pointer
|
||||
app unsafe.Pointer
|
||||
app *C.struct_Application
|
||||
|
||||
// Manages menus
|
||||
menuManager *menumanager.Manager
|
||||
|
|
@ -123,7 +123,7 @@ func (a *Application) Run(incomingDispatcher Dispatcher, bindings string, debug
|
|||
app := C.NewApplication(title, width, height, resizable, devtools, fullscreen, startHidden, logLevel)
|
||||
|
||||
// Save app reference
|
||||
a.app = unsafe.Pointer(app)
|
||||
a.app = (*C.struct_Application)(app)
|
||||
|
||||
// Set Min Window Size
|
||||
minWidth := C.int(a.config.MinWidth)
|
||||
|
|
|
|||
|
|
@ -2,42 +2,44 @@
|
|||
#define __FFENESTRI_H__
|
||||
|
||||
#include <stdio.h>
|
||||
struct Application;
|
||||
|
||||
extern void *NewApplication(const char *title, int width, int height, int resizable, int devtools, int fullscreen, int startHidden, int logLevel);
|
||||
extern void SetMinWindowSize(void *app, int minWidth, int minHeight);
|
||||
extern void SetMaxWindowSize(void *app, int maxWidth, int maxHeight);
|
||||
extern void Run(void *app, int argc, char **argv);
|
||||
extern void DestroyApplication(void *app);
|
||||
extern void SetDebug(void *app, int flag);
|
||||
extern void SetBindings(void *app, const char *bindings);
|
||||
extern void ExecJS(void *app, const char *script);
|
||||
extern void Hide(void *app);
|
||||
extern void Show(void *app);
|
||||
extern void Center(void *app);
|
||||
extern void Maximise(void *app);
|
||||
extern void Unmaximise(void *app);
|
||||
extern void ToggleMaximise(void *app);
|
||||
extern void Minimise(void *app);
|
||||
extern void Unminimise(void *app);
|
||||
extern void ToggleMinimise(void *app);
|
||||
extern void SetColour(void *app, int red, int green, int blue, int alpha);
|
||||
extern void SetSize(void *app, int width, int height);
|
||||
extern void SetPosition(void *app, int x, int y);
|
||||
extern void Quit(void *app);
|
||||
extern void SetTitle(void *app, const char *title);
|
||||
extern void Fullscreen(void *app);
|
||||
extern void UnFullscreen(void *app);
|
||||
extern void ToggleFullscreen(void *app);
|
||||
extern void DisableFrame(void *app);
|
||||
extern void OpenDialog(void *appPointer, char *callbackID, char *title, char *filters, char *defaultFilename, char *defaultDir, int allowFiles, int allowDirs, int allowMultiple, int showHiddenFiles, int canCreateDirectories, int resolvesAliases, int treatPackagesAsDirectories);
|
||||
extern void SaveDialog(void *appPointer, char *callbackID, char *title, char *filters, char *defaultFilename, char *defaultDir, int showHiddenFiles, int canCreateDirectories, int treatPackagesAsDirectories);
|
||||
extern void MessageDialog(void *appPointer, char *callbackID, char *type, char *title, char *message, char *icon, char *button1, char *button2, char *button3, char *button4, char *defaultButton, char *cancelButton);
|
||||
extern void DarkModeEnabled(void *appPointer, char *callbackID);
|
||||
extern void SetApplicationMenu(void *, const char *);
|
||||
extern void UpdateTray(void *app, char *menuAsJSON);
|
||||
extern void UpdateContextMenus(void *app, char *contextMenusAsJSON);
|
||||
extern void UpdateTrayLabel(void *app, const char *label);
|
||||
extern void UpdateTrayIcon(void *app, const char *label);
|
||||
extern void AddTrayMenu(void *app, const char *trayAsJSON);
|
||||
extern struct Application *NewApplication(const char *title, int width, int height, int resizable, int devtools, int fullscreen, int startHidden, int logLevel);
|
||||
extern void SetMinWindowSize(struct Application*, int minWidth, int minHeight);
|
||||
extern void SetMaxWindowSize(struct Application*, int maxWidth, int maxHeight);
|
||||
extern void Run(struct Application*, int argc, char **argv);
|
||||
extern void DestroyApplication(struct Application*);
|
||||
extern void SetDebug(struct Application*, int flag);
|
||||
extern void SetBindings(struct Application*, const char *bindings);
|
||||
extern void ExecJS(struct Application*, const char *script);
|
||||
extern void Hide(struct Application*);
|
||||
extern void Show(struct Application*);
|
||||
extern void Center(struct Application*);
|
||||
extern void Maximise(struct Application*);
|
||||
extern void Unmaximise(struct Application*);
|
||||
extern void ToggleMaximise(struct Application*);
|
||||
extern void Minimise(struct Application*);
|
||||
extern void Unminimise(struct Application*);
|
||||
extern void ToggleMinimise(struct Application*);
|
||||
extern void SetColour(struct Application*, int red, int green, int blue, int alpha);
|
||||
extern void SetSize(struct Application*, int width, int height);
|
||||
extern void SetPosition(struct Application*, int x, int y);
|
||||
extern void Quit(struct Application*);
|
||||
extern void SetTitle(struct Application*, const char *title);
|
||||
extern void Fullscreen(struct Application*);
|
||||
extern void UnFullscreen(struct Application*);
|
||||
extern void ToggleFullscreen(struct Application*);
|
||||
extern void DisableFrame(struct Application*);
|
||||
extern void OpenDialog(struct Application*, char *callbackID, char *title, char *filters, char *defaultFilename, char *defaultDir, int allowFiles, int allowDirs, int allowMultiple, int showHiddenFiles, int canCreateDirectories, int resolvesAliases, int treatPackagesAsDirectories);
|
||||
extern void SaveDialog(struct Application*, char *callbackID, char *title, char *filters, char *defaultFilename, char *defaultDir, int showHiddenFiles, int canCreateDirectories, int treatPackagesAsDirectories);
|
||||
extern void MessageDialog(struct Application*, char *callbackID, char *type, char *title, char *message, char *icon, char *button1, char *button2, char *button3, char *button4, char *defaultButton, char *cancelButton);
|
||||
extern void DarkModeEnabled(struct Application*, char *callbackID);
|
||||
extern void SetApplicationMenu(struct Application*, const char *);
|
||||
extern void UpdateTray(struct Application*, char *menuAsJSON);
|
||||
extern void UpdateContextMenus(struct Application*, char *contextMenusAsJSON);
|
||||
extern void UpdateTrayLabel(struct Application*, const char *label);
|
||||
extern void UpdateTrayIcon(struct Application*, const char *label);
|
||||
extern void AddTrayMenu(struct Application*, const char *trayAsJSON);
|
||||
extern void UpdateTrayMenu(struct Application*, const char *trayAsJSON);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -206,6 +206,10 @@ func (c *Client) UpdateTray(menu *menu.Menu) {
|
|||
C.UpdateTray(c.app.app, c.app.string2CString(string(trayMenuJSON)))
|
||||
}
|
||||
|
||||
func (c *Client) UpdateTrayMenu(trayMenuJSON string) {
|
||||
C.UpdateTrayMenu(c.app.app, c.app.string2CString(trayMenuJSON))
|
||||
}
|
||||
|
||||
func (c *Client) UpdateTrayLabel(label string) {
|
||||
C.UpdateTrayLabel(c.app.app, c.app.string2CString(label))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -925,6 +925,10 @@ void AddTrayMenu(struct Application *app, const char *trayJSON) {
|
|||
AddTrayMenuToStore(app->trayMenuStore, trayJSON);
|
||||
}
|
||||
|
||||
void UpdateTrayMenu(struct Application *app, const char* trayJSON) {
|
||||
UpdateTrayMenuInStore(app->trayMenuStore, trayJSON);
|
||||
}
|
||||
|
||||
void SetBindings(struct Application *app, const char *bindings) {
|
||||
const char* temp = concat("window.wailsbindings = \"", bindings);
|
||||
const char* jscall = concat(temp, "\";");
|
||||
|
|
|
|||
|
|
@ -7,19 +7,7 @@ package ffenestri
|
|||
#include "ffenestri.h"
|
||||
#include "ffenestri_darwin.h"
|
||||
|
||||
extern void TitlebarAppearsTransparent(void *);
|
||||
extern void HideTitle(void *);
|
||||
extern void HideTitleBar(void *);
|
||||
extern void FullSizeContent(void *);
|
||||
extern void UseToolbar(void *);
|
||||
extern void HideToolbarSeparator(void *);
|
||||
extern void DisableFrame(void *);
|
||||
extern void SetAppearance(void *, const char *);
|
||||
extern void WebviewIsTransparent(void *);
|
||||
extern void WindowBackgroundIsTranslucent(void *);
|
||||
extern void SetTray(void *, const char *, const char *, const char *);
|
||||
extern void SetContextMenus(void *, const char *);
|
||||
extern void AddTrayMenu(void *, const char *);
|
||||
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
|
|
|||
|
|
@ -94,7 +94,20 @@
|
|||
#define NSAlertSecondButtonReturn 1001
|
||||
#define NSAlertThirdButtonReturn 1002
|
||||
|
||||
struct Application;
|
||||
int releaseNSObject(void *const context, struct hashmap_element_s *const e);
|
||||
|
||||
void TitlebarAppearsTransparent(struct Application* app);
|
||||
void HideTitle(struct Application* app);
|
||||
void HideTitleBar(struct Application* app);
|
||||
void FullSizeContent(struct Application* app);
|
||||
void UseToolbar(struct Application* app);
|
||||
void HideToolbarSeparator(struct Application* app);
|
||||
void DisableFrame(struct Application* app);
|
||||
void SetAppearance(struct Application* app, const char *);
|
||||
void WebviewIsTransparent(struct Application* app);
|
||||
void WindowBackgroundIsTranslucent(struct Application* app);
|
||||
void SetTray(struct Application* app, const char *, const char *, const char *);
|
||||
void SetContextMenus(struct Application* app, const char *);
|
||||
void AddTrayMenu(struct Application* app, const char *);
|
||||
|
||||
#endif
|
||||
|
|
@ -28,6 +28,10 @@ Menu* NewMenu(JsonNode *menuData) {
|
|||
ABORT("[NewMenu] Not enough memory to allocate radioGroupMap!");
|
||||
}
|
||||
|
||||
// Init other members
|
||||
result->menu = NULL;
|
||||
result->parentData = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -77,12 +81,18 @@ void DeleteMenu(Menu *menu) {
|
|||
hashmap_destroy(&menu->radioGroupMap);
|
||||
|
||||
// Free up the processed menu memory
|
||||
json_delete(menu->processedMenu);
|
||||
if (menu->processedMenu != NULL) {
|
||||
json_delete(menu->processedMenu);
|
||||
menu->processedMenu = NULL;
|
||||
}
|
||||
|
||||
// Release the vector memory
|
||||
vec_deinit(&menu->callbackDataCache);
|
||||
|
||||
msg(menu->menu, s("release"));
|
||||
// Free nsmenu if we have it
|
||||
if ( menu->menu != NULL ) {
|
||||
msg(menu->menu, s("release"));
|
||||
}
|
||||
|
||||
free(menu);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ TrayMenu* NewTrayMenu(const char* menuJSON) {
|
|||
ABORT("[NewTrayMenu] Unable to parse TrayMenu JSON: %s", menuJSON);
|
||||
}
|
||||
|
||||
// Save reference to this json
|
||||
result->processedJSON = processedJSON;
|
||||
|
||||
// TODO: Make this configurable
|
||||
result->trayIconPosition = NSImageLeft;
|
||||
|
||||
|
|
@ -43,7 +46,7 @@ TrayMenu* NewTrayMenu(const char* menuJSON) {
|
|||
}
|
||||
|
||||
void DumpTrayMenu(TrayMenu* trayMenu) {
|
||||
printf(" ['%s':%p] = { label: '%s', icon: '%s', menu: %p }\n", trayMenu->ID, trayMenu, trayMenu->label, trayMenu->icon, trayMenu->menu );
|
||||
printf(" ['%s':%p] = { label: '%s', icon: '%s', menu: %p, statusbar: %p }\n", trayMenu->ID, trayMenu, trayMenu->label, trayMenu->icon, trayMenu->menu, trayMenu->statusbaritem );
|
||||
}
|
||||
|
||||
void ShowTrayMenu(TrayMenu* trayMenu) {
|
||||
|
|
@ -53,16 +56,19 @@ void ShowTrayMenu(TrayMenu* trayMenu) {
|
|||
id statusBar = msg( c("NSStatusBar"), s("systemStatusBar") );
|
||||
trayMenu->statusbaritem = msg(statusBar, s("statusItemWithLength:"), NSVariableStatusItemLength);
|
||||
msg(trayMenu->statusbaritem, s("retain"));
|
||||
id statusBarButton = msg(trayMenu->statusbaritem, s("button"));
|
||||
msg(statusBarButton, s("setImagePosition:"), trayMenu->trayIconPosition);
|
||||
|
||||
// Update the icon if needed
|
||||
UpdateTrayMenuIcon(trayMenu);
|
||||
|
||||
// Update the label if needed
|
||||
UpdateTrayMenuLabel(trayMenu);
|
||||
}
|
||||
|
||||
id statusBarButton = msg(trayMenu->statusbaritem, s("button"));
|
||||
msg(statusBarButton, s("setImagePosition:"), trayMenu->trayIconPosition);
|
||||
|
||||
// Update the icon if needed
|
||||
UpdateTrayMenuIcon(trayMenu);
|
||||
|
||||
// Update the label if needed
|
||||
UpdateTrayMenuLabel(trayMenu);
|
||||
|
||||
// Update the menu
|
||||
id menu = GetMenu(trayMenu->menu);
|
||||
msg(trayMenu->statusbaritem, s("setMenu:"), menu);
|
||||
}
|
||||
|
|
@ -80,7 +86,7 @@ void UpdateTrayMenuLabel(TrayMenu *trayMenu) {
|
|||
|
||||
void UpdateTrayMenuIcon(TrayMenu *trayMenu) {
|
||||
|
||||
// Exit early if NULL or emptystring
|
||||
// Exit early if NULL or empty string
|
||||
if( trayMenu->icon == NULL || STREMPTY(trayMenu->icon ) ) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -90,6 +96,30 @@ void UpdateTrayMenuIcon(TrayMenu *trayMenu) {
|
|||
msg(statusBarButton, s("setImage:"), trayImage);
|
||||
}
|
||||
|
||||
// UpdateTrayMenuInPlace receives 2 menus. The current menu gets
|
||||
// updated with the data from the new menu.
|
||||
void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu) {
|
||||
|
||||
// Delete the old menu
|
||||
DeleteMenu(currentMenu->menu);
|
||||
|
||||
// Set the new one
|
||||
currentMenu->menu = newMenu->menu;
|
||||
|
||||
// Delete the old JSON
|
||||
json_delete(currentMenu->processedJSON);
|
||||
|
||||
// Set the new JSON
|
||||
currentMenu->processedJSON = newMenu->processedJSON;
|
||||
|
||||
// Copy the other data
|
||||
currentMenu->ID = newMenu->ID;
|
||||
currentMenu->label = newMenu->label;
|
||||
currentMenu->trayIconPosition = newMenu->trayIconPosition;
|
||||
currentMenu->icon = newMenu->icon;
|
||||
|
||||
}
|
||||
|
||||
void DeleteTrayMenu(TrayMenu* trayMenu) {
|
||||
|
||||
// printf("Freeing TrayMenu:\n");
|
||||
|
|
@ -99,10 +129,17 @@ void DeleteTrayMenu(TrayMenu* trayMenu) {
|
|||
DeleteMenu(trayMenu->menu);
|
||||
|
||||
// Free JSON
|
||||
json_delete(trayMenu->processedJSON);
|
||||
if (trayMenu->processedJSON != NULL ) {
|
||||
json_delete(trayMenu->processedJSON);
|
||||
}
|
||||
|
||||
// Free the status item
|
||||
msg(trayMenu->statusbaritem, s("release"));
|
||||
if ( trayMenu->statusbaritem != NULL ) {
|
||||
id statusBar = msg( c("NSStatusBar"), s("systemStatusBar") );
|
||||
msg(statusBar, s("removeStatusItem:"), trayMenu->statusbaritem);
|
||||
msg(trayMenu->statusbaritem, s("release"));
|
||||
trayMenu->statusbaritem = NULL;
|
||||
}
|
||||
|
||||
// Free the tray menu memory
|
||||
MEMFREE(trayMenu);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ typedef struct {
|
|||
TrayMenu* NewTrayMenu(const char *trayJSON);
|
||||
void DumpTrayMenu(TrayMenu* trayMenu);
|
||||
void ShowTrayMenu(TrayMenu* trayMenu);
|
||||
void UpdateTrayMenuInPlace(TrayMenu* currentMenu, TrayMenu* newMenu);
|
||||
void UpdateTrayMenuIcon(TrayMenu *trayMenu);
|
||||
void UpdateTrayMenuLabel(TrayMenu *trayMenu);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ TrayMenuStore* NewTrayMenuStore() {
|
|||
|
||||
TrayMenuStore* result = malloc(sizeof(TrayMenuStore));
|
||||
|
||||
// Allocate Context Menu Store
|
||||
// Allocate Tray Menu Store
|
||||
if( 0 != hashmap_create((const unsigned)4, &result->trayMenuMap)) {
|
||||
ABORT("[NewTrayMenuStore] Not enough memory to allocate trayMenuMap!");
|
||||
}
|
||||
|
|
@ -19,16 +19,25 @@ TrayMenuStore* NewTrayMenuStore() {
|
|||
return result;
|
||||
}
|
||||
|
||||
int dumpTrayMenu(void *const context, struct hashmap_element_s *const e) {
|
||||
DumpTrayMenu(e->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DumpTrayMenuStore(TrayMenuStore* store) {
|
||||
hashmap_iterate_pairs(&store->trayMenuMap, dumpTrayMenu, NULL);
|
||||
}
|
||||
|
||||
void AddTrayMenuToStore(TrayMenuStore* store, const char* menuJSON) {
|
||||
TrayMenu* newMenu = NewTrayMenu(menuJSON);
|
||||
|
||||
hashmap_put(&store->trayMenuMap, newMenu->ID, strlen(newMenu->ID), newMenu);
|
||||
|
||||
}
|
||||
|
||||
int showTrayMenu(void *const context, struct hashmap_element_s *const e) {
|
||||
ShowTrayMenu(e->data);
|
||||
return -1;
|
||||
// 0 to retain element, -1 to delete.
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ShowTrayMenusInStore(TrayMenuStore* store) {
|
||||
|
|
@ -43,15 +52,54 @@ int freeTrayMenu(void *const context, struct hashmap_element_s *const e) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
void DeleteTrayMenuStore(TrayMenuStore *trayMenuStore) {
|
||||
void DeleteTrayMenuStore(TrayMenuStore *store) {
|
||||
|
||||
// Delete context menus
|
||||
if (hashmap_num_entries(&trayMenuStore->trayMenuMap) > 0) {
|
||||
if (0 != hashmap_iterate_pairs(&trayMenuStore->trayMenuMap, freeTrayMenu, NULL)) {
|
||||
if (hashmap_num_entries(&store->trayMenuMap) > 0) {
|
||||
if (0 != hashmap_iterate_pairs(&store->trayMenuMap, freeTrayMenu, NULL)) {
|
||||
ABORT("[DeleteContextMenuStore] Failed to release contextMenuStore entries!");
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy tray menu map
|
||||
hashmap_destroy(&trayMenuStore->trayMenuMap);
|
||||
hashmap_destroy(&store->trayMenuMap);
|
||||
}
|
||||
|
||||
TrayMenu* GetTrayMenuFromStore(TrayMenuStore* store, const char* menuID) {
|
||||
// Get the current menu
|
||||
return hashmap_get(&store->trayMenuMap, menuID, strlen(menuID));
|
||||
}
|
||||
|
||||
void UpdateTrayMenuInStore(TrayMenuStore* store, const char* menuJSON) {
|
||||
TrayMenu* newMenu = NewTrayMenu(menuJSON);
|
||||
|
||||
// Get the current menu
|
||||
TrayMenu *currentMenu = GetTrayMenuFromStore(store, newMenu->ID);
|
||||
if ( currentMenu == NULL ) {
|
||||
ABORT("Attempted to update unknown tray menu with ID '%s'.", newMenu->ID);
|
||||
}
|
||||
|
||||
// Save the status bar reference
|
||||
newMenu->statusbaritem = currentMenu->statusbaritem;
|
||||
|
||||
hashmap_remove(&store->trayMenuMap, newMenu->ID, strlen(newMenu->ID));
|
||||
|
||||
// Delete the current menu
|
||||
DeleteMenu(currentMenu->menu);
|
||||
currentMenu->menu = NULL;
|
||||
|
||||
// Free JSON
|
||||
if (currentMenu->processedJSON != NULL ) {
|
||||
json_delete(currentMenu->processedJSON);
|
||||
currentMenu->processedJSON = NULL;
|
||||
}
|
||||
|
||||
// Free the tray menu memory
|
||||
MEMFREE(currentMenu);
|
||||
|
||||
hashmap_put(&store->trayMenuMap, newMenu->ID, strlen(newMenu->ID), newMenu);
|
||||
|
||||
// Show the updated menu
|
||||
ShowTrayMenu(newMenu);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ typedef struct {
|
|||
TrayMenuStore* NewTrayMenuStore();
|
||||
|
||||
void AddTrayMenuToStore(TrayMenuStore* store, const char* menuJSON);
|
||||
void UpdateTrayMenuInStore(TrayMenuStore* store, const char* menuJSON);
|
||||
void ShowTrayMenusInStore(TrayMenuStore* store);
|
||||
void DeleteTrayMenuStore(TrayMenuStore* store);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@ type Manager struct {
|
|||
// Context menus
|
||||
contextMenus map[string]*ContextMenu
|
||||
|
||||
// Tray menus
|
||||
trayMenus map[string]*TrayMenu
|
||||
// Tray menu stores
|
||||
trayMenus map[string]*TrayMenu
|
||||
trayMenuPointers map[*menu.TrayMenu]string
|
||||
}
|
||||
|
||||
func NewManager() *Manager {
|
||||
|
|
@ -26,6 +27,7 @@ func NewManager() *Manager {
|
|||
applicationMenuItemMap: NewMenuItemMap(),
|
||||
contextMenus: make(map[string]*ContextMenu),
|
||||
trayMenus: make(map[string]*TrayMenu),
|
||||
trayMenuPointers: make(map[*menu.TrayMenu]string),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,17 @@ type TrayMenu struct {
|
|||
ProcessedMenu *WailsMenu
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
result := &TrayMenu{
|
||||
ID: generateTrayID(),
|
||||
Label: trayMenu.Label,
|
||||
Icon: trayMenu.Icon,
|
||||
menu: trayMenu.Menu,
|
||||
|
|
@ -45,17 +52,40 @@ func NewTrayMenu(trayMenu *menu.TrayMenu) *TrayMenu {
|
|||
|
||||
func (m *Manager) AddTrayMenu(trayMenu *menu.TrayMenu) {
|
||||
newTrayMenu := NewTrayMenu(trayMenu)
|
||||
m.trayMenus[newTrayMenu.ID] = newTrayMenu
|
||||
|
||||
// Hook up a new ID
|
||||
trayID := generateTrayID()
|
||||
newTrayMenu.ID = trayID
|
||||
|
||||
// Save the references
|
||||
m.trayMenus[trayID] = newTrayMenu
|
||||
m.trayMenuPointers[trayMenu] = trayID
|
||||
}
|
||||
|
||||
func (m *Manager) UpdateTrayMenu(trayMenu *menu.TrayMenu) (string, error) {
|
||||
trayID, trayMenuKnown := m.trayMenuPointers[trayMenu]
|
||||
if !trayMenuKnown {
|
||||
return "", fmt.Errorf("unknown Tray Menu '%s'. Please add the tray menu using AddTrayMenu()", trayMenu.Label)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
data, err := json.Marshal(trayMenu)
|
||||
JSON, err := trayMenu.AsJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, string(data))
|
||||
result = append(result, JSON)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ type Client interface {
|
|||
UpdateTray(menu *menu.Menu)
|
||||
UpdateTrayLabel(label string)
|
||||
UpdateTrayIcon(name string)
|
||||
UpdateTrayMenu(menuJSON string)
|
||||
UpdateContextMenus(contextMenus *menu.ContextMenus)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -464,6 +464,20 @@ func (d *Dispatcher) processMenuMessage(result *servicebus.Message) {
|
|||
client.frontend.UpdateMenu(updatedMenu)
|
||||
}
|
||||
|
||||
case "updatetraymenu":
|
||||
updatedTrayMenu, ok := result.Data().(string)
|
||||
if !ok {
|
||||
d.logger.Error("Invalid data for 'menufrontend:updatetraymenu' : %#v",
|
||||
result.Data())
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: Work out what we mean in a multi window environment...
|
||||
// For now we will just pick the first one
|
||||
for _, client := range d.clients {
|
||||
client.frontend.UpdateTrayMenu(updatedTrayMenu)
|
||||
}
|
||||
|
||||
default:
|
||||
d.logger.Error("Unknown menufrontend command: %s", command)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
type Menu interface {
|
||||
UpdateApplicationMenu()
|
||||
UpdateContextMenu(contextMenu *menu.ContextMenu)
|
||||
UpdateTrayMenu(trayMenu *menu.TrayMenu)
|
||||
}
|
||||
|
||||
type menuRuntime struct {
|
||||
|
|
@ -29,3 +30,7 @@ func (m *menuRuntime) UpdateApplicationMenu() {
|
|||
func (m *menuRuntime) UpdateContextMenu(contextMenu *menu.ContextMenu) {
|
||||
m.bus.Publish("menu:updatecontextmenu", contextMenu)
|
||||
}
|
||||
|
||||
func (m *menuRuntime) UpdateTrayMenu(trayMenu *menu.TrayMenu) {
|
||||
m.bus.Publish("menu:updatetraymenu", trayMenu)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package subsystem
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
|
|
@ -119,6 +120,16 @@ func (m *Menu) Start() error {
|
|||
//
|
||||
//// Notify frontend of menu change
|
||||
//m.bus.Publish("menufrontend:updatecontextmenu", updatedMenu)
|
||||
case "updatetraymenu":
|
||||
trayMenu := menuMessage.Data().(*menu.TrayMenu)
|
||||
updatedMenu, err := m.menuManager.UpdateTrayMenu(trayMenu)
|
||||
if err != nil {
|
||||
m.logger.Trace("%s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Notify frontend of menu change
|
||||
m.bus.Publish("menufrontend:updatetraymenu", updatedMenu)
|
||||
|
||||
default:
|
||||
m.logger.Error("unknown menu message: %+v", menuMessage)
|
||||
|
|
|
|||
|
|
@ -3,16 +3,17 @@ package main
|
|||
import (
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Tray struct
|
||||
type Tray struct {
|
||||
runtime *wails.Runtime
|
||||
//
|
||||
//dynamicMenuCounter int
|
||||
//lock sync.Mutex
|
||||
//dynamicMenuItems map[string]*menu.MenuItem
|
||||
//anotherDynamicMenuCounter int
|
||||
|
||||
dynamicMenuCounter int
|
||||
lock sync.Mutex
|
||||
dynamicMenuItems map[string]*menu.MenuItem
|
||||
|
||||
trayMenu *menu.TrayMenu
|
||||
secondTrayMenu *menu.TrayMenu
|
||||
|
|
@ -24,23 +25,7 @@ type Tray struct {
|
|||
func (t *Tray) WailsInit(runtime *wails.Runtime) error {
|
||||
// Perform your setup here
|
||||
t.runtime = runtime
|
||||
//
|
||||
//// Setup Menu Listeners
|
||||
//t.runtime.Tray.On("Show Window", func(mi *menu.MenuItem) {
|
||||
// t.runtime.Window.Show()
|
||||
//})
|
||||
//t.runtime.Tray.On("Hide Window", func(mi *menu.MenuItem) {
|
||||
// t.runtime.Window.Hide()
|
||||
//})
|
||||
//
|
||||
//t.runtime.Tray.On("Minimise Window", func(mi *menu.MenuItem) {
|
||||
// t.runtime.Window.Minimise()
|
||||
//})
|
||||
//
|
||||
//t.runtime.Tray.On("Unminimise Window", func(mi *menu.MenuItem) {
|
||||
// t.runtime.Window.Unminimise()
|
||||
//})
|
||||
//
|
||||
|
||||
//// Auto switch between light / dark tray icons
|
||||
//t.runtime.Events.OnThemeChange(func(darkMode bool) {
|
||||
// if darkMode {
|
||||
|
|
@ -74,45 +59,16 @@ func (t *Tray) WailsShutdown() {
|
|||
t.done = true
|
||||
}
|
||||
|
||||
//func (t *Tray) incrementcounter() int {
|
||||
// t.dynamicMenuCounter++
|
||||
// return t.dynamicMenuCounter
|
||||
//}
|
||||
//
|
||||
//func (t *Tray) decrementcounter() int {
|
||||
// t.dynamicMenuCounter--
|
||||
// return t.dynamicMenuCounter
|
||||
//}
|
||||
//
|
||||
//func (t *Tray) addMenu(mi *menu.MenuItem) {
|
||||
//
|
||||
// // Lock because this method will be called in a gorouting
|
||||
// t.lock.Lock()
|
||||
// defer t.lock.Unlock()
|
||||
//
|
||||
// // Get this menu's parent
|
||||
// parent := mi.Parent()
|
||||
// counter := t.incrementcounter()
|
||||
// menuText := "Dynamic Menu Item " + strconv.Itoa(counter)
|
||||
// parent.Append(menu.Text(menuText, menuText, nil, nil))
|
||||
// // parent.Append(menu.Text(menuText, menuText, menu.Key("[")))
|
||||
//
|
||||
// // If this is the first dynamic menu added, let's add a remove menu item
|
||||
// if counter == 1 {
|
||||
// removeMenu := menu.Text("Remove "+menuText,
|
||||
// "Remove Last Item", keys.CmdOrCtrl("-"), nil)
|
||||
// parent.Prepend(removeMenu)
|
||||
// t.runtime.Tray.On("Remove Last Item", t.removeMenu)
|
||||
// } else {
|
||||
// removeMenu := t.runtime.Tray.GetByID("Remove Last Item")
|
||||
// // Test if the remove menu hasn't already been removed in another thread
|
||||
// if removeMenu != nil {
|
||||
// removeMenu.Label = "Remove " + menuText
|
||||
// }
|
||||
// }
|
||||
// t.runtime.Tray.Update()
|
||||
//}
|
||||
//
|
||||
func (t *Tray) incrementcounter() int {
|
||||
t.dynamicMenuCounter++
|
||||
return t.dynamicMenuCounter
|
||||
}
|
||||
|
||||
func (t *Tray) decrementcounter() int {
|
||||
t.dynamicMenuCounter--
|
||||
return t.dynamicMenuCounter
|
||||
}
|
||||
|
||||
//func (t *Tray) removeMenu(_ *menu.MenuItem) {
|
||||
//
|
||||
// // Lock because this method will be called in a goroutine
|
||||
|
|
@ -164,10 +120,16 @@ func (t *Tray) createTrayMenus() []*menu.TrayMenu {
|
|||
secondTrayMenu := &menu.TrayMenu{}
|
||||
secondTrayMenu.Label = "Another tray label"
|
||||
secondTrayMenu.Menu = menu.NewMenuFromItems(
|
||||
menu.Text("Show Window", "Show Window", nil, t.showWindow),
|
||||
menu.Text("Hide Window", "Hide Window", nil, t.hideWindow),
|
||||
menu.Text("Minimise Window", "Minimise Window", nil, t.minimiseWindow),
|
||||
menu.Text("Unminimise Window", "Unminimise Window", nil, t.unminimiseWindow),
|
||||
menu.Text("Update Label", "Update Label", nil, func(_ *menu.CallbackData) {
|
||||
// Lock because this method will be called in a goroutine
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
|
||||
counter := t.incrementcounter()
|
||||
trayLabel := "Updated Label " + strconv.Itoa(counter)
|
||||
secondTrayMenu.Label = trayLabel
|
||||
t.runtime.Menu.UpdateTrayMenu(t.secondTrayMenu)
|
||||
}),
|
||||
)
|
||||
t.secondTrayMenu = secondTrayMenu
|
||||
return []*menu.TrayMenu{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue