From 3f82ceabbacedc32f41d62579ac63e9b013789da Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 30 Apr 2022 12:00:00 +1000 Subject: [PATCH 01/48] Initial Tray support for Mac --- .gitignore | 1 + .../frontend/desktop/darwin/AppDelegate.m | 2 + .../frontend/desktop/darwin/Application.h | 4 + .../frontend/desktop/darwin/Application.m | 15 ++++ .../frontend/desktop/darwin/frontend.go | 78 +++++++++++++++---- v2/internal/frontend/desktop/darwin/menu.go | 14 ++++ v2/internal/frontend/desktop/darwin/message.h | 1 + .../frontend/desktop/darwin/traymenu.go | 36 +++++++++ v2/internal/frontend/desktop/darwin/window.go | 4 + v2/internal/frontend/frontend.go | 3 + v2/pkg/menu/tray.go | 31 +++++++- v2/pkg/options/options.go | 7 +- 12 files changed, 178 insertions(+), 18 deletions(-) create mode 100644 v2/internal/frontend/desktop/darwin/traymenu.go diff --git a/.gitignore b/.gitignore index 32e4ec11e..d621a4358 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ v2/test/kitchensink/frontend/package.json.md5 !v2/internal/ffenestri/windows/x64/WebView2Loader.dll .idea/ v2/cmd/wails/internal/commands/initialise/templates/testtemplates/ +v2/internal/frontend/desktop/darwin/test.xcodeproj \ No newline at end of file diff --git a/v2/internal/frontend/desktop/darwin/AppDelegate.m b/v2/internal/frontend/desktop/darwin/AppDelegate.m index 6d46deae4..c985fb9b6 100644 --- a/v2/internal/frontend/desktop/darwin/AppDelegate.m +++ b/v2/internal/frontend/desktop/darwin/AppDelegate.m @@ -9,6 +9,7 @@ #import #import "AppDelegate.h" +#import "message.h" @implementation AppDelegate - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { @@ -25,6 +26,7 @@ } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + processNotification(0); // Notify Go [NSApp activateIgnoringOtherApps:YES]; if ( self.startFullscreen ) { NSWindowCollectionBehavior behaviour = [self.mainWindow collectionBehavior]; diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index 41423965a..363461107 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -57,6 +57,10 @@ void AppendRole(void *inctx, void *inMenu, int role); void SetAsApplicationMenu(void *inctx, void *inMenu); void UpdateApplicationMenu(void *inctx); +/* Tray Menu */ +void* NewNSStatusItem(const char* label); +void SetTrayMenu(void *nsStatusItem, void* nsMenu); + 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); void AppendSeparator(void* inMenu); diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index da1ffac16..2f82c5aad 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -270,6 +270,21 @@ 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 SetTrayMenu(void *nsStatusItem, void* nsMenu) { + ON_MAIN_THREAD( + [(NSStatusItem*)nsStatusItem setMenu:(NSMenu *)nsMenu]; + ) +} + + void* NewMenu(const char *name) { NSString *title = @""; if (name != nil) { diff --git a/v2/internal/frontend/desktop/darwin/frontend.go b/v2/internal/frontend/desktop/darwin/frontend.go index 1d0dbb75d..492d42b32 100644 --- a/v2/internal/frontend/desktop/darwin/frontend.go +++ b/v2/internal/frontend/desktop/darwin/frontend.go @@ -3,15 +3,6 @@ package darwin -/* -#cgo CFLAGS: -x objective-c -#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit -#import -#import "Application.h" -#import "WailsContext.h" - -#include -*/ import "C" import ( "bytes" @@ -31,14 +22,33 @@ import ( "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/frontend/assetserver" "github.com/wailsapp/wails/v2/internal/logger" + "github.com/wailsapp/wails/v2/pkg/menu" "github.com/wailsapp/wails/v2/pkg/options" ) +/* +#cgo CFLAGS: -x objective-c +#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit +#import +#import "Application.h" +#import "WailsContext.h" + +#include +*/ +import "C" + const startURL = "wails://wails/" +type NotificationType uint8 + +const ( + ApplicationDidFinishLaunching NotificationType = 0 +) + var messageBuffer = make(chan string, 100) var requestBuffer = make(chan *request, 100) var callbackBuffer = make(chan uint, 10) +var notificationBuffer = make(chan NotificationType, 10) type Frontend struct { @@ -57,15 +67,22 @@ type Frontend struct { mainWindow *Window bindings *binding.Bindings dispatcher frontend.Dispatcher + trayMenus map[*menu.TrayMenu]*NSTrayMenu + + applicationDidFinishLaunching bool + notificationCallbacks map[NotificationType][]func() + trayMenusBuffer []*menu.TrayMenu } func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) *Frontend { result := &Frontend{ - frontendOptions: appoptions, - logger: myLogger, - bindings: appBindings, - dispatcher: dispatcher, - ctx: ctx, + frontendOptions: appoptions, + logger: myLogger, + bindings: appBindings, + dispatcher: dispatcher, + ctx: ctx, + trayMenus: make(map[*menu.TrayMenu]*NSTrayMenu), + notificationCallbacks: make(map[NotificationType][]func()), } result.startURL, _ = url.Parse(startURL) @@ -88,10 +105,17 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger. go result.startMessageProcessor() go result.startCallbackProcessor() + go result.startNotificationsProcessor() + + result.registerNotificationCallback(ApplicationDidFinishLaunching, result.processTrayMenus) return result } +func (f *Frontend) registerNotificationCallback(notificationType NotificationType, callback func()) { + f.notificationCallbacks[notificationType] = append(f.notificationCallbacks[notificationType], callback) +} + func (f *Frontend) startMessageProcessor() { for message := range messageBuffer { f.processMessage(message) @@ -110,6 +134,11 @@ func (f *Frontend) startCallbackProcessor() { } } } +func (f *Frontend) startNotificationsProcessor() { + for notification := range notificationBuffer { + f.handleNotification(notification) + } +} func (f *Frontend) WindowReload() { f.ExecJS("runtime.WindowReload();") @@ -393,6 +422,11 @@ func processMessage(message *C.char) { messageBuffer <- goMessage } +//export processNotification +func processNotification(notification NotificationType) { + notificationBuffer <- notification +} + //export processURLRequest func processURLRequest(ctx unsafe.Pointer, url *C.char, method *C.char, headers *C.char, body unsafe.Pointer, bodyLen C.int) { var goBody []byte @@ -413,3 +447,19 @@ func processURLRequest(ctx unsafe.Pointer, url *C.char, method *C.char, headers func processCallback(callbackID uint) { callbackBuffer <- callbackID } + +func (f *Frontend) handleNotification(notification NotificationType) { + switch notification { + case ApplicationDidFinishLaunching: + f.applicationDidFinishLaunching = true + for _, callback := range f.notificationCallbacks[notification] { + go callback() + } + } +} + +func (f *Frontend) processTrayMenus() { + for _, trayMenu := range f.trayMenusBuffer { + f.mainWindow.TrayMenuAdd(trayMenu) + } +} diff --git a/v2/internal/frontend/desktop/darwin/menu.go b/v2/internal/frontend/desktop/darwin/menu.go index 8afb63fb9..65449f7f2 100644 --- a/v2/internal/frontend/desktop/darwin/menu.go +++ b/v2/internal/frontend/desktop/darwin/menu.go @@ -20,6 +20,20 @@ import ( "github.com/wailsapp/wails/v2/pkg/menu/keys" ) +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{ + context: context, + nsStatusItem: nsStatusItem, + } +} + type NSMenu struct { context unsafe.Pointer nsmenu unsafe.Pointer diff --git a/v2/internal/frontend/desktop/darwin/message.h b/v2/internal/frontend/desktop/darwin/message.h index f0a5f482b..8ea2bda3e 100644 --- a/v2/internal/frontend/desktop/darwin/message.h +++ b/v2/internal/frontend/desktop/darwin/message.h @@ -20,6 +20,7 @@ void processMessageDialogResponse(int); void processOpenFileDialogResponse(const char*); void processSaveFileDialogResponse(const char*); void processCallback(int); +void processNotification(int); #ifdef __cplusplus } diff --git a/v2/internal/frontend/desktop/darwin/traymenu.go b/v2/internal/frontend/desktop/darwin/traymenu.go new file mode 100644 index 000000000..3b214edf8 --- /dev/null +++ b/v2/internal/frontend/desktop/darwin/traymenu.go @@ -0,0 +1,36 @@ +package darwin + +/* +#cgo CFLAGS: -x objective-c +#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit +#import +#import "Application.h" +#import "WailsContext.h" + +#include +*/ + +import "C" +import ( + "unsafe" + + "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 + } + nsTrayMenu := f.mainWindow.TrayMenuAdd(trayMenu) + f.trayMenus[trayMenu] = nsTrayMenu +} + +type NSTrayMenu struct { + context unsafe.Pointer + nsStatusItem unsafe.Pointer // NSStatusItem +} + +func (w *Window) TrayMenuAdd(trayMenu *menu.TrayMenu) *NSTrayMenu { + return NewNSTrayMenu(w.context, trayMenu) +} diff --git a/v2/internal/frontend/desktop/darwin/window.go b/v2/internal/frontend/desktop/darwin/window.go index ec6e20d46..2437b5126 100644 --- a/v2/internal/frontend/desktop/darwin/window.go +++ b/v2/internal/frontend/desktop/darwin/window.go @@ -112,6 +112,10 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window { result.SetApplicationMenu(frontendOptions.Menu) } + if frontendOptions.TrayMenu != nil { + result.TrayMenuAdd(frontendOptions.TrayMenu) + } + return result } diff --git a/v2/internal/frontend/frontend.go b/v2/internal/frontend/frontend.go index 6dd12c6b0..473712198 100644 --- a/v2/internal/frontend/frontend.go +++ b/v2/internal/frontend/frontend.go @@ -101,4 +101,7 @@ type Frontend interface { // Browser BrowserOpenURL(url string) + + // Tray Menu + TrayMenuAdd(trayMenu *menu.TrayMenu) } diff --git a/v2/pkg/menu/tray.go b/v2/pkg/menu/tray.go index 7554795ad..87cca6629 100644 --- a/v2/pkg/menu/tray.go +++ b/v2/pkg/menu/tray.go @@ -1,7 +1,18 @@ package menu +import ( + "context" + "log" + goruntime "runtime" +) + +type TrayMenuAdd interface { + TrayMenuAdd(menu *TrayMenu) +} + // TrayMenu are the options type TrayMenu struct { + ctx context.Context // Label is the text we wish to display in the tray Label string @@ -27,7 +38,7 @@ type TrayMenu struct { Tooltip string // Callback function when menu clicked - //Click Callback `json:"-"` + Click Callback // Disabled makes the item unselectable Disabled bool @@ -41,3 +52,21 @@ type TrayMenu struct { // OnClose is called when the Menu is closed OnClose func() } + +func NewTrayMenu(ctx context.Context) *TrayMenu { + return &TrayMenu{ + ctx: ctx, + } +} + +func (t *TrayMenu) Show() { + result := t.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) + +} diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 1e0b9dfca..e75793903 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -56,9 +56,10 @@ type App struct { //ContextMenus []*menu.ContextMenu //TrayMenus []*menu.TrayMenu - Windows *windows.Options - Mac *mac.Options - Linux *linux.Options + Windows *windows.Options + Mac *mac.Options + Linux *linux.Options + TrayMenu *menu.TrayMenu } type RGBA struct { From ee501703740cc4d85039d57b28130a8010e249aa Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 30 Apr 2022 17:51:11 +1000 Subject: [PATCH 02/48] Support activation policy --- .../frontend/desktop/darwin/AppDelegate.h | 1 + .../frontend/desktop/darwin/AppDelegate.m | 3 ++- .../frontend/desktop/darwin/Application.h | 2 +- .../frontend/desktop/darwin/Application.m | 9 ++++----- .../frontend/desktop/darwin/WailsContext.h | 1 + .../frontend/desktop/darwin/frontend.go | 6 +++++- v2/internal/frontend/desktop/darwin/window.go | 4 ++-- v2/pkg/options/mac/mac.go | 18 +++++++++--------- 8 files changed, 25 insertions(+), 19 deletions(-) diff --git a/v2/internal/frontend/desktop/darwin/AppDelegate.h b/v2/internal/frontend/desktop/darwin/AppDelegate.h index e2dd841c9..56399ee9f 100644 --- a/v2/internal/frontend/desktop/darwin/AppDelegate.h +++ b/v2/internal/frontend/desktop/darwin/AppDelegate.h @@ -17,6 +17,7 @@ @property bool startHidden; @property bool startFullscreen; @property (retain) WailsWindow* mainWindow; +@property int activationPolicy; @end diff --git a/v2/internal/frontend/desktop/darwin/AppDelegate.m b/v2/internal/frontend/desktop/darwin/AppDelegate.m index c985fb9b6..0f47caf67 100644 --- a/v2/internal/frontend/desktop/darwin/AppDelegate.m +++ b/v2/internal/frontend/desktop/darwin/AppDelegate.m @@ -26,7 +26,8 @@ } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - processNotification(0); // Notify Go + processNotification(0); // Notify Go + [NSApp setActivationPolicy:self.activationPolicy]; [NSApp activateIgnoringOtherApps:YES]; if ( self.startFullscreen ) { NSWindowCollectionBehavior behaviour = [self.mainWindow collectionBehavior]; diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index 363461107..91d04ba90 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -18,7 +18,7 @@ #define WindowStartsFullscreen 3 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); -void Run(void*, const char* url); +void Run(void *inctx, const char* url, int activationPolicy); void SetTitle(void* ctx, const char *title); void Center(void* ctx); diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index 2f82c5aad..131ef2353 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -19,7 +19,7 @@ WailsContext* Create(const char* title, int width, int height, int frameless, in WailsContext *result = [WailsContext new]; result.debug = debug; - + if ( windowStartState == WindowStartsFullscreen ) { fullscreen = 1; } @@ -27,7 +27,7 @@ WailsContext* Create(const char* title, int width, int height, int frameless, in [result CreateWindow:width :height :frameless :resizable :fullscreen :fullSizeContent :hideTitleBar :titlebarAppearsTransparent :hideTitle :useToolbar :hideToolbarSeparator :webviewIsTransparent :hideWindowOnClose :safeInit(appearance) :windowIsTranslucent :minWidth :minHeight :maxWidth :maxHeight]; [result SetTitle:safeInit(title)]; [result Center]; - + switch( windowStartState ) { case WindowStartsMaximised: [result.mainWindow zoom:nil]; @@ -344,12 +344,11 @@ void AppendSeparator(void* inMenu) { [menu AppendSeparator]; } - - -void Run(void *inctx, const char* url) { +void Run(void *inctx, const char* url, int activationPolicy) { WailsContext *ctx = (__bridge WailsContext*) inctx; NSApplication *app = [NSApplication sharedApplication]; AppDelegate* delegate = [AppDelegate new]; + delegate.activationPolicy = activationPolicy; [app setDelegate:(id)delegate]; ctx.appdelegate = delegate; delegate.mainWindow = ctx.mainWindow; diff --git a/v2/internal/frontend/desktop/darwin/WailsContext.h b/v2/internal/frontend/desktop/darwin/WailsContext.h index b51d62f47..f4b4ca848 100644 --- a/v2/internal/frontend/desktop/darwin/WailsContext.h +++ b/v2/internal/frontend/desktop/darwin/WailsContext.h @@ -23,6 +23,7 @@ @property NSSize userMinSize; @property NSSize userMaxSize; +@property int activationPolicy; - (BOOL) canBecomeKeyWindow; - (void) applyWindowConstraints; diff --git a/v2/internal/frontend/desktop/darwin/frontend.go b/v2/internal/frontend/desktop/darwin/frontend.go index 492d42b32..fa34bce6f 100644 --- a/v2/internal/frontend/desktop/darwin/frontend.go +++ b/v2/internal/frontend/desktop/darwin/frontend.go @@ -178,7 +178,11 @@ func (f *Frontend) Run(ctx context.Context) error { f.frontendOptions.OnStartup(f.ctx) } }() - mainWindow.Run(f.startURL.String()) + var activationPolicy C.int + if f.frontendOptions != nil && f.frontendOptions.Mac != nil { + activationPolicy = C.int(f.frontendOptions.Mac.ActivationPolicy) + } + mainWindow.Run(f.startURL.String(), activationPolicy) return nil } diff --git a/v2/internal/frontend/desktop/darwin/window.go b/v2/internal/frontend/desktop/darwin/window.go index 2437b5126..38cfb0b14 100644 --- a/v2/internal/frontend/desktop/darwin/window.go +++ b/v2/internal/frontend/desktop/darwin/window.go @@ -123,9 +123,9 @@ func (w *Window) Center() { C.Center(w.context) } -func (w *Window) Run(url string) { +func (w *Window) Run(url string, activationPolicy C.int) { _url := C.CString(url) - C.Run(w.context, _url) + C.Run(w.context, _url, activationPolicy) C.free(unsafe.Pointer(_url)) } diff --git a/v2/pkg/options/mac/mac.go b/v2/pkg/options/mac/mac.go index 033cfd1a2..2f574607f 100644 --- a/v2/pkg/options/mac/mac.go +++ b/v2/pkg/options/mac/mac.go @@ -1,12 +1,12 @@ package mac -//type ActivationPolicy int -// -//const ( -// NSApplicationActivationPolicyRegular ActivationPolicy = 0 -// NSApplicationActivationPolicyAccessory ActivationPolicy = 1 -// NSApplicationActivationPolicyProhibited ActivationPolicy = 2 -//) +type ActivationPolicy int + +const ( + NSApplicationActivationPolicyRegular ActivationPolicy = 0 + NSApplicationActivationPolicyAccessory ActivationPolicy = 1 + NSApplicationActivationPolicyProhibited ActivationPolicy = 2 +) type AboutInfo struct { Title string @@ -20,7 +20,7 @@ type Options struct { Appearance AppearanceType WebviewIsTransparent bool WindowIsTranslucent bool - //ActivationPolicy ActivationPolicy - About *AboutInfo + About *AboutInfo + ActivationPolicy ActivationPolicy //URLHandlers map[string]func(string) } From 1830c64c79fb8a72d98fb108c7a94f6fbecac012 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 30 Apr 2022 21:39:19 +1000 Subject: [PATCH 03/48] Better Checked implementation --- v2/internal/frontend/desktop/darwin/Application.h | 1 + v2/internal/frontend/desktop/darwin/Application.m | 4 ++++ v2/internal/frontend/desktop/darwin/menu.go | 5 +++++ v2/pkg/menu/menuitem.go | 15 +++++++++++++++ 4 files changed, 25 insertions(+) diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index 91d04ba90..9c61eaae8 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -56,6 +56,7 @@ void AppendSubmenu(void* parent, void* child); void AppendRole(void *inctx, void *inMenu, int role); void SetAsApplicationMenu(void *inctx, void *inMenu); void UpdateApplicationMenu(void *inctx); +void SetMenuItemChecked(void* nsMenuItem, int checked); /* Tray Menu */ void* NewNSStatusItem(const char* label); diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index 131ef2353..9106b2983 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -165,6 +165,10 @@ void ToggleMaximise(void* inctx) { ); } +void SetMenuItemChecked(void* nsMenuItem, int checked) { + [(NSMenuItem*)nsMenuItem setState:(checked == 0 ? NSOffState : NSOnState)]; +} + const char* GetSize(void *inctx) { WailsContext *ctx = (__bridge WailsContext*) inctx; NSRect frame = [ctx.mainWindow frame]; diff --git a/v2/internal/frontend/desktop/darwin/menu.go b/v2/internal/frontend/desktop/darwin/menu.go index 65449f7f2..fc60f0c3b 100644 --- a/v2/internal/frontend/desktop/darwin/menu.go +++ b/v2/internal/frontend/desktop/darwin/menu.go @@ -67,6 +67,10 @@ type MenuItem struct { radioGroupMembers []*MenuItem } +func (m *MenuItem) SetChecked(value bool) { + C.SetMenuItemChecked(m.nsmenuitem, bool2Cint(value)) +} + func (m *NSMenu) AddMenuItem(menuItem *menu.MenuItem) *MenuItem { c := NewCalloc() defer c.Free() @@ -83,6 +87,7 @@ func (m *NSMenu) AddMenuItem(menuItem *menu.MenuItem) *MenuItem { result.id = createMenuItemID(result) result.nsmenuitem = C.AppendMenuItem(m.context, m.nsmenu, c.String(menuItem.Label), key, modifier, bool2Cint(menuItem.Disabled), bool2Cint(menuItem.Checked), C.int(result.id)) + menuItem.Impl = result return result } diff --git a/v2/pkg/menu/menuitem.go b/v2/pkg/menu/menuitem.go index ba9574eb3..165a4ddeb 100644 --- a/v2/pkg/menu/menuitem.go +++ b/v2/pkg/menu/menuitem.go @@ -6,6 +6,10 @@ import ( "github.com/wailsapp/wails/v2/pkg/menu/keys" ) +type MenuItemImpl interface { + SetChecked(bool) +} + // MenuItem represents a menuitem contained in a menu type MenuItem struct { // Label is what appears as the menu text @@ -53,6 +57,9 @@ type MenuItem struct { // Used for locking when removing elements removeLock sync.Mutex + + // Implementation of the runtime methods + Impl MenuItemImpl } // Parent returns the parent of the menu item. @@ -216,6 +223,14 @@ func (m *MenuItem) insertItemAtIndex(index int, target *MenuItem) bool { return true } +func (m *MenuItem) SetChecked(b bool) { + if m.Checked != b { + println("here!!!!!") + m.Checked = b + m.Impl.SetChecked(b) + } +} + // Text is a helper to create basic Text menu items func Text(label string, accelerator *keys.Accelerator, click Callback) *MenuItem { return &MenuItem{ From ae0933c82a54880ccb8d1e8cb0ebf499dfb5f973 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 2 May 2022 18:57:35 +1000 Subject: [PATCH 04/48] Move TrayMenu from config to runtime Support better tray menu API Move object creation to main thread --- .../frontend/desktop/darwin/Application.h | 5 +- .../frontend/desktop/darwin/Application.m | 48 ++- v2/internal/frontend/desktop/darwin/menu.go | 70 +++- v2/internal/frontend/desktop/darwin/message.h | 1 + .../frontend/desktop/darwin/traymenu.go | 13 +- v2/internal/frontend/desktop/darwin/window.go | 4 - v2/internal/frontend/frontend.go | 2 +- v2/internal/menumanager/contextmenu.go | 106 ++--- v2/internal/menumanager/menumanager.go | 1 + v2/internal/menumanager/traymenu.go | 363 +++++++++--------- v2/pkg/menu/tray.go | 69 +++- v2/pkg/options/options.go | 7 +- 12 files changed, 408 insertions(+), 281 deletions(-) diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index 9c61eaae8..5600706f7 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -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 */ diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index 9106b2983..7f1436809 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -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]; diff --git a/v2/internal/frontend/desktop/darwin/menu.go b/v2/internal/frontend/desktop/darwin/menu.go index fc60f0c3b..c80efe3d3 100644 --- a/v2/internal/frontend/desktop/darwin/menu.go +++ b/v2/internal/frontend/desktop/darwin/menu.go @@ -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 { diff --git a/v2/internal/frontend/desktop/darwin/message.h b/v2/internal/frontend/desktop/darwin/message.h index 8ea2bda3e..a6e27ee0d 100644 --- a/v2/internal/frontend/desktop/darwin/message.h +++ b/v2/internal/frontend/desktop/darwin/message.h @@ -21,6 +21,7 @@ void processOpenFileDialogResponse(const char*); void processSaveFileDialogResponse(const char*); void processCallback(int); void processNotification(int); +void objectCreated(int, void*); #ifdef __cplusplus } diff --git a/v2/internal/frontend/desktop/darwin/traymenu.go b/v2/internal/frontend/desktop/darwin/traymenu.go index 3b214edf8..8ba366f30 100644 --- a/v2/internal/frontend/desktop/darwin/traymenu.go +++ b/v2/internal/frontend/desktop/darwin/traymenu.go @@ -9,7 +9,6 @@ package darwin #include */ - 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) } diff --git a/v2/internal/frontend/desktop/darwin/window.go b/v2/internal/frontend/desktop/darwin/window.go index 38cfb0b14..ed409b973 100644 --- a/v2/internal/frontend/desktop/darwin/window.go +++ b/v2/internal/frontend/desktop/darwin/window.go @@ -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 } diff --git a/v2/internal/frontend/frontend.go b/v2/internal/frontend/frontend.go index 473712198..6cf14855f 100644 --- a/v2/internal/frontend/frontend.go +++ b/v2/internal/frontend/frontend.go @@ -103,5 +103,5 @@ type Frontend interface { BrowserOpenURL(url string) // Tray Menu - TrayMenuAdd(trayMenu *menu.TrayMenu) + TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl } diff --git a/v2/internal/menumanager/contextmenu.go b/v2/internal/menumanager/contextmenu.go index 77c47891c..b87b476b7 100644 --- a/v2/internal/menumanager/contextmenu.go +++ b/v2/internal/menumanager/contextmenu.go @@ -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() +//} diff --git a/v2/internal/menumanager/menumanager.go b/v2/internal/menumanager/menumanager.go index ea7939415..92756edff 100644 --- a/v2/internal/menumanager/menumanager.go +++ b/v2/internal/menumanager/menumanager.go @@ -2,6 +2,7 @@ package menumanager import ( "fmt" + "github.com/wailsapp/wails/v2/pkg/menu" ) diff --git a/v2/internal/menumanager/traymenu.go b/v2/internal/menumanager/traymenu.go index aed5b05ac..ebbbe7c3b 100644 --- a/v2/internal/menumanager/traymenu.go +++ b/v2/internal/menumanager/traymenu.go @@ -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 +//} diff --git a/v2/pkg/menu/tray.go b/v2/pkg/menu/tray.go index 87cca6629..6507f7c67 100644 --- a/v2/pkg/menu/tray.go +++ b/v2/pkg/menu/tray.go @@ -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 /trayicons and - // the filenames are used as IDs, minus the extension - // EG: /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) + } +} diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index e75793903..1e0b9dfca 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -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 { From 58b6e4c3353efaff3537d44a435334cb263b741a Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 2 May 2022 20:16:04 +1000 Subject: [PATCH 05/48] Support retina images --- .../frontend/desktop/darwin/Application.h | 2 ++ .../frontend/desktop/darwin/Application.m | 5 +++++ v2/internal/frontend/desktop/darwin/menu.go | 17 ++++++++++++++--- v2/internal/frontend/desktop/darwin/traymenu.go | 3 ++- v2/internal/frontend/desktop/darwin/window.go | 4 ++++ v2/pkg/menu/tray.go | 1 + 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index 5600706f7..85562e996 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -72,4 +72,6 @@ NSString* safeInit(const char* input); void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int template, int position); +bool IsRetina(void *ctx); + #endif /* Application_h */ diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index 7f1436809..5c933c231 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -378,6 +378,11 @@ void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int ) } +bool IsRetina(void *ctx) { + CGFloat scale = [((WailsContext*)ctx).mainWindow backingScaleFactor]; + return scale != (CGFloat)1; +} + void Run(void *inctx, const char* url, int activationPolicy) { WailsContext *ctx = (__bridge WailsContext*) inctx; NSApplication *app = [NSApplication sharedApplication]; diff --git a/v2/internal/frontend/desktop/darwin/menu.go b/v2/internal/frontend/desktop/darwin/menu.go index c80efe3d3..02c0bcaef 100644 --- a/v2/internal/frontend/desktop/darwin/menu.go +++ b/v2/internal/frontend/desktop/darwin/menu.go @@ -46,7 +46,7 @@ func objectCreated(id uint32, pointer unsafe.Pointer) { createNSObjectMapLock.Unlock() } -func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu) *NSTrayMenu { +func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu, isRetina bool) *NSTrayMenu { c := NewCalloc() defer c.Free() @@ -57,6 +57,7 @@ func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu) *NSTrayMenu result := &NSTrayMenu{ context: context, nsStatusItem: nsStatusItem, + isRetina: isRetina, } if trayMenu.Label != "" { @@ -77,11 +78,21 @@ func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu) *NSTrayMenu } func (n *NSTrayMenu) SetImage(image *menu.TrayImage) { - if image.Image == nil { + + if !n.isRetina && image.Image == nil { return } + + var imagePtr unsafe.Pointer + if image.Image != nil { + imagePtr = unsafe.Pointer(&image.Image[0]) + } + if n.isRetina && image.Image2x != nil { + imagePtr = unsafe.Pointer(&image.Image2x[0]) + } + C.SetTrayImage(n.nsStatusItem, - unsafe.Pointer(&image.Image[0]), + imagePtr, C.int(len(image.Image)), bool2Cint(image.IsTemplate), C.int(image.Position), diff --git a/v2/internal/frontend/desktop/darwin/traymenu.go b/v2/internal/frontend/desktop/darwin/traymenu.go index 8ba366f30..3213b11dc 100644 --- a/v2/internal/frontend/desktop/darwin/traymenu.go +++ b/v2/internal/frontend/desktop/darwin/traymenu.go @@ -25,6 +25,7 @@ func (f *Frontend) TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl { type NSTrayMenu struct { context unsafe.Pointer nsStatusItem unsafe.Pointer // NSStatusItem + isRetina bool } func (n *NSTrayMenu) SetLabel(label string) { @@ -33,5 +34,5 @@ func (n *NSTrayMenu) SetLabel(label string) { } func (w *Window) TrayMenuAdd(trayMenu *menu.TrayMenu) *NSTrayMenu { - return NewNSTrayMenu(w.context, trayMenu) + return NewNSTrayMenu(w.context, trayMenu, IsRetina(w)) } diff --git a/v2/internal/frontend/desktop/darwin/window.go b/v2/internal/frontend/desktop/darwin/window.go index ed409b973..781739f31 100644 --- a/v2/internal/frontend/desktop/darwin/window.go +++ b/v2/internal/frontend/desktop/darwin/window.go @@ -40,6 +40,10 @@ func bool2Cint(value bool) C.int { return C.int(0) } +func IsRetina(window *Window) bool { + return bool(C.IsRetina(window.context)) +} + func NewWindow(frontendOptions *options.App, debugMode bool) *Window { c := NewCalloc() diff --git a/v2/pkg/menu/tray.go b/v2/pkg/menu/tray.go index 6507f7c67..2dcda3da4 100644 --- a/v2/pkg/menu/tray.go +++ b/v2/pkg/menu/tray.go @@ -31,6 +31,7 @@ const ( type TrayImage struct { Image []byte + Image2x []byte IsTemplate bool Position ImagePosition } From 13fb5352d87c7547a5b5225c02e71c69c1b97810 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 3 May 2022 08:31:42 +1000 Subject: [PATCH 06/48] Support sizing tray menu --- .../frontend/desktop/darwin/Application.h | 2 +- .../frontend/desktop/darwin/Application.m | 22 +++++++++++++++---- v2/internal/frontend/desktop/darwin/menu.go | 12 +++++----- v2/pkg/menu/tray.go | 14 +++++++++--- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index 85562e996..ef7eab723 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -59,7 +59,7 @@ void UpdateApplicationMenu(void *inctx); void SetMenuItemChecked(void* nsMenuItem, int checked); /* Tray Menu */ -void NewNSStatusItem(int); +void NewNSStatusItem(int id, int length); void SetTrayMenu(void *nsStatusItem, void* nsMenu); void SetTrayMenuLabel(void *nsStatusItem, const char *label); diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index 5c933c231..9ef1c8109 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -275,12 +275,24 @@ void AppendRole(void *inctx, void *inMenu, int role) { [menu appendRole :ctx :role]; } -void NewNSStatusItem(int id) { - ON_MAIN_THREAD( +void NewNSStatusItem(int id, int length) { + dispatch_async(dispatch_get_main_queue(), ^{ + NSStatusBar *statusBar = [NSStatusBar systemStatusBar]; - NSStatusItem *result = [[statusBar statusItemWithLength:NSVariableStatusItemLength] retain]; + // Map Go to Cocoa length. 0 = NSVariableStatusItemLength. + CGFloat length = NSVariableStatusItemLength; + if( length == 1 ) { + length = NSSquareStatusItemLength; + } + NSStatusItem *result = [[statusBar statusItemWithLength:length] retain]; objectCreated(id,result); - ) + + }); +} + +void DeleteStatusItem(void *_nsStatusItem) { + NSStatusItem *nsStatusItem = (NSStatusItem*) _nsStatusItem; + [nsStatusItem release]; } void SetTrayMenuLabel(void *_nsStatusItem, const char *label) { @@ -365,6 +377,7 @@ void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int if(template) { image.template = true; } + image.size = NSMakeSize(22.0, 22.0); statusItem.button.image = image; // Swap NSNoImage and NSImageLeading because we wanted NSImageLeading to be default in Go @@ -375,6 +388,7 @@ void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int actualPosition = 7; } [statusItem.button setImagePosition:actualPosition]; + ) } diff --git a/v2/internal/frontend/desktop/darwin/menu.go b/v2/internal/frontend/desktop/darwin/menu.go index 02c0bcaef..c9755a4ab 100644 --- a/v2/internal/frontend/desktop/darwin/menu.go +++ b/v2/internal/frontend/desktop/darwin/menu.go @@ -52,7 +52,7 @@ func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu, isRetina boo id := uuid.New().ID() nsStatusItem := waitNSObjectCreate(id, func() { - C.NewNSStatusItem(C.int(id)) + C.NewNSStatusItem(C.int(id), C.int(trayMenu.Sizing)) }) result := &NSTrayMenu{ context: context, @@ -83,17 +83,17 @@ func (n *NSTrayMenu) SetImage(image *menu.TrayImage) { return } - var imagePtr unsafe.Pointer + var imageToUse []byte if image.Image != nil { - imagePtr = unsafe.Pointer(&image.Image[0]) + imageToUse = image.Image } if n.isRetina && image.Image2x != nil { - imagePtr = unsafe.Pointer(&image.Image2x[0]) + imageToUse = image.Image2x } C.SetTrayImage(n.nsStatusItem, - imagePtr, - C.int(len(image.Image)), + unsafe.Pointer(&imageToUse[0]), + C.int(len(imageToUse)), bool2Cint(image.IsTemplate), C.int(image.Position), ) diff --git a/v2/pkg/menu/tray.go b/v2/pkg/menu/tray.go index 2dcda3da4..cb46d0faa 100644 --- a/v2/pkg/menu/tray.go +++ b/v2/pkg/menu/tray.go @@ -29,6 +29,13 @@ const ( NSImageTrailing ImagePosition = 8 ) +type TraySizing int + +const ( + Variable TraySizing = 0 + Square TraySizing = 1 +) + type TrayImage struct { Image []byte Image2x []byte @@ -45,9 +52,6 @@ type TrayMenu struct { Image *TrayImage - // MacTemplateImage indicates that on a Mac, this image is a template image - MacTemplateImage bool - // Text Colour RGBA string @@ -73,6 +77,10 @@ type TrayMenu struct { // OnClose is called when the Menu is closed OnClose func() + /* Mac Options */ + Sizing TraySizing + + // This is the reference to the OS specific implementation impl TrayMenuImpl } From 1947a9a17ab363ee886f7ab49ae63affd12b9e4c Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 5 May 2022 21:15:50 +1000 Subject: [PATCH 07/48] Hugely improved + darkmode bitmap support. Dynamic scaling factor support --- .../frontend/desktop/darwin/Application.h | 2 +- .../frontend/desktop/darwin/Application.m | 4 +- v2/internal/frontend/desktop/darwin/menu.go | 53 +++++------ .../frontend/desktop/darwin/traymenu.go | 11 ++- v2/internal/frontend/desktop/darwin/window.go | 4 +- v2/pkg/events/events.go | 3 + v2/pkg/menu/menu.go | 9 +- v2/pkg/menu/menuitem.go | 1 - v2/pkg/menu/tray.go | 89 ++++++++++++++++--- 9 files changed, 121 insertions(+), 55 deletions(-) create mode 100644 v2/pkg/events/events.go diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index ef7eab723..ba2accc00 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -72,6 +72,6 @@ NSString* safeInit(const char* input); void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int template, int position); -bool IsRetina(void *ctx); +int ScalingFactor(void *ctx); #endif /* Application_h */ diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index 9ef1c8109..f2a847861 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -392,9 +392,9 @@ void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int ) } -bool IsRetina(void *ctx) { +int ScalingFactor(void *ctx) { CGFloat scale = [((WailsContext*)ctx).mainWindow backingScaleFactor]; - return scale != (CGFloat)1; + return (int)scale; } void Run(void *inctx, const char* url, int activationPolicy) { diff --git a/v2/internal/frontend/desktop/darwin/menu.go b/v2/internal/frontend/desktop/darwin/menu.go index c9755a4ab..5ab4bed19 100644 --- a/v2/internal/frontend/desktop/darwin/menu.go +++ b/v2/internal/frontend/desktop/darwin/menu.go @@ -14,6 +14,7 @@ package darwin */ import "C" import ( + "fmt" "sync" "unsafe" @@ -46,7 +47,7 @@ func objectCreated(id uint32, pointer unsafe.Pointer) { createNSObjectMapLock.Unlock() } -func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu, isRetina bool) *NSTrayMenu { +func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu, scalingFactor int) *NSTrayMenu { c := NewCalloc() defer c.Free() @@ -55,52 +56,42 @@ func NewNSTrayMenu(context unsafe.Pointer, trayMenu *menu.TrayMenu, isRetina boo C.NewNSStatusItem(C.int(id), C.int(trayMenu.Sizing)) }) result := &NSTrayMenu{ - context: context, - nsStatusItem: nsStatusItem, - isRetina: isRetina, + context: context, + nsStatusItem: nsStatusItem, + scalingFactor: scalingFactor, } - if trayMenu.Label != "" { - result.SetLabel(trayMenu.Label) - } + result.SetLabel(trayMenu.Label) + result.SetMenu(trayMenu.Menu) + result.SetImage(trayMenu.Image) - // 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 !n.isRetina && image.Image == nil { + if image == nil { return } - - var imageToUse []byte - if image.Image != nil { - imageToUse = image.Image + bitmap := image.GetBestBitmap(n.scalingFactor, false) + if bitmap == nil { + fmt.Printf("[Warning] No TrayMenu Image available for scaling factor %dx\n", n.scalingFactor) + return } - if n.isRetina && image.Image2x != nil { - imageToUse = image.Image2x - } - C.SetTrayImage(n.nsStatusItem, - unsafe.Pointer(&imageToUse[0]), - C.int(len(imageToUse)), + unsafe.Pointer(&bitmap[0]), + C.int(len(bitmap)), bool2Cint(image.IsTemplate), C.int(image.Position), ) } -func (n *NSTrayMenu) SetMenu(menu *NSMenu) { - C.SetTrayMenu(n.nsStatusItem, menu.nsmenu) +func (n *NSTrayMenu) SetMenu(menu *menu.Menu) { + if menu == nil { + return + } + theMenu := NewNSMenu(n.context, "") + processMenu(theMenu, menu) + C.SetTrayMenu(n.nsStatusItem, theMenu.nsmenu) } type NSMenu struct { diff --git a/v2/internal/frontend/desktop/darwin/traymenu.go b/v2/internal/frontend/desktop/darwin/traymenu.go index 3213b11dc..faf4ec984 100644 --- a/v2/internal/frontend/desktop/darwin/traymenu.go +++ b/v2/internal/frontend/desktop/darwin/traymenu.go @@ -23,16 +23,19 @@ func (f *Frontend) TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl { } type NSTrayMenu struct { - context unsafe.Pointer - nsStatusItem unsafe.Pointer // NSStatusItem - isRetina bool + context unsafe.Pointer + nsStatusItem unsafe.Pointer // NSStatusItem + scalingFactor int } func (n *NSTrayMenu) SetLabel(label string) { + if label == "" { + return + } cLabel := C.CString(label) C.SetTrayMenuLabel(n.nsStatusItem, cLabel) } func (w *Window) TrayMenuAdd(trayMenu *menu.TrayMenu) *NSTrayMenu { - return NewNSTrayMenu(w.context, trayMenu, IsRetina(w)) + return NewNSTrayMenu(w.context, trayMenu, ScalingFactor(w)) } diff --git a/v2/internal/frontend/desktop/darwin/window.go b/v2/internal/frontend/desktop/darwin/window.go index 781739f31..8a1769b44 100644 --- a/v2/internal/frontend/desktop/darwin/window.go +++ b/v2/internal/frontend/desktop/darwin/window.go @@ -40,8 +40,8 @@ func bool2Cint(value bool) C.int { return C.int(0) } -func IsRetina(window *Window) bool { - return bool(C.IsRetina(window.context)) +func ScalingFactor(window *Window) int { + return int(C.ScalingFactor(window.context)) } func NewWindow(frontendOptions *options.App, debugMode bool) *Window { diff --git a/v2/pkg/events/events.go b/v2/pkg/events/events.go new file mode 100644 index 000000000..40727ba1a --- /dev/null +++ b/v2/pkg/events/events.go @@ -0,0 +1,3 @@ +package events + +const ThemeChanged = ":wails:themechanged" diff --git a/v2/pkg/menu/menu.go b/v2/pkg/menu/menu.go index 0c3ddb618..b5f27c739 100644 --- a/v2/pkg/menu/menu.go +++ b/v2/pkg/menu/menu.go @@ -44,9 +44,10 @@ func (m *Menu) AddRadio(label string, checked bool, accelerator *keys.Accelerato } // AddSeparator adds a separator to the menu -func (m *Menu) AddSeparator() { +func (m *Menu) AddSeparator() *MenuItem { item := Separator() m.Append(item) + return item } func (m *Menu) AddSubmenu(label string) *Menu { @@ -56,6 +57,12 @@ func (m *Menu) AddSubmenu(label string) *Menu { return submenu } +func (m *Menu) InsertSubmenu(label string, submenu *Menu) *Menu { + item := SubMenu(label, submenu) + m.Append(item) + return submenu +} + func (m *Menu) Prepend(item *MenuItem) { m.Items = append([]*MenuItem{item}, m.Items...) } diff --git a/v2/pkg/menu/menuitem.go b/v2/pkg/menu/menuitem.go index 165a4ddeb..1cefe2259 100644 --- a/v2/pkg/menu/menuitem.go +++ b/v2/pkg/menu/menuitem.go @@ -225,7 +225,6 @@ func (m *MenuItem) insertItemAtIndex(index int, target *MenuItem) bool { func (m *MenuItem) SetChecked(b bool) { if m.Checked != b { - println("here!!!!!") m.Checked = b m.Impl.SetChecked(b) } diff --git a/v2/pkg/menu/tray.go b/v2/pkg/menu/tray.go index cb46d0faa..1c8ec07b4 100644 --- a/v2/pkg/menu/tray.go +++ b/v2/pkg/menu/tray.go @@ -4,6 +4,8 @@ import ( "context" "log" goruntime "runtime" + + "github.com/wailsapp/wails/v2/pkg/events" ) type TrayMenuAdd interface { @@ -13,20 +15,25 @@ type TrayMenuAdd interface { type TrayMenuImpl interface { SetLabel(string) SetImage(*TrayImage) + SetMenu(*Menu) +} + +type EventsImpl interface { + On(eventName string, callback func(...interface{})) } 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 + ImageLeading ImagePosition = 0 + ImageOnly ImagePosition = 1 + ImageLeft ImagePosition = 2 + ImageRight ImagePosition = 3 + ImageBelow ImagePosition = 4 + ImageAbove ImagePosition = 5 + ImageOverlaps ImagePosition = 6 + NoImage ImagePosition = 7 + ImageTrailing ImagePosition = 8 ) type TraySizing int @@ -37,10 +44,42 @@ const ( ) type TrayImage struct { - Image []byte - Image2x []byte - IsTemplate bool - Position ImagePosition + // Bitmaps hold images for different scaling factors + // First = 1x, Second = 2x, etc + Bitmaps [][]byte + BitmapsDark [][]byte + IsTemplate bool + Position ImagePosition +} + +func (t *TrayImage) getBestBitmap(scale int, isDarkMode bool) []byte { + bitmapsToCheck := t.Bitmaps + if isDarkMode { + bitmapsToCheck = t.BitmapsDark + } + if scale < 1 || scale >= len(bitmapsToCheck) { + return nil + } + for i := scale; i > 0; i-- { + if bitmapsToCheck[i] != nil { + return bitmapsToCheck[i] + } + } + return nil +} + +// GetBestBitmap will attempt to return the best bitmap for the theme +// If dark theme is used and no dark theme bitmap exists, then it will +// revert to light theme bitmaps +func (t *TrayImage) GetBestBitmap(scale int, isDarkMode bool) []byte { + var result []byte + if isDarkMode { + result = t.getBestBitmap(scale, true) + if result != nil { + return result + } + } + return t.getBestBitmap(scale, false) } // TrayMenu are the options @@ -82,6 +121,9 @@ type TrayMenu struct { // This is the reference to the OS specific implementation impl TrayMenuImpl + + // Theme change callback + themeChangeCallback func(data ...interface{}) } func NewTrayMenu() *TrayMenu { @@ -101,6 +143,20 @@ func (t *TrayMenu) Show(ctx context.Context) { } t.impl = result.(TrayMenuAdd).TrayMenuAdd(t) + if t.themeChangeCallback == nil { + t.themeChangeCallback = func(data ...interface{}) { + println("Update button image") + if t.Image != nil { + // Update the image + t.SetImage(t.Image) + } + } + result := ctx.Value("events") + if result != nil { + result.(EventsImpl).On(events.ThemeChanged, t.themeChangeCallback) + } + } + } func (t *TrayMenu) SetLabel(label string) { @@ -116,3 +172,10 @@ func (t *TrayMenu) SetImage(image *TrayImage) { t.impl.SetImage(image) } } + +func (t *TrayMenu) SetMenu(menu *Menu) { + t.Menu = menu + if t.impl != nil { + t.impl.SetMenu(menu) + } +} From ee5ca1a84aaf1f6b704455a096732df78b3a77da Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 7 May 2022 20:39:08 +1000 Subject: [PATCH 08/48] Add SetLabel, minor api updates --- .../frontend/desktop/darwin/Application.h | 5 ++++- .../frontend/desktop/darwin/Application.m | 20 ++++++++++++++++--- v2/internal/frontend/desktop/darwin/menu.go | 5 +++++ v2/internal/frontend/devserver/devserver.go | 4 ++++ v2/pkg/menu/menu.go | 8 ++++---- v2/pkg/menu/menuitem.go | 9 +++++++++ 6 files changed, 43 insertions(+), 8 deletions(-) diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index ba2accc00..10a3aa638 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -62,6 +62,10 @@ void SetMenuItemChecked(void* nsMenuItem, int checked); void NewNSStatusItem(int id, int length); void SetTrayMenu(void *nsStatusItem, void* nsMenu); void SetTrayMenuLabel(void *nsStatusItem, const char *label); +void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int template, int position); + +/* MenuItems */ +void SetMenuItemLabel(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); @@ -70,7 +74,6 @@ void UpdateMenuItem(void* nsmenuitem, int checked); NSString* safeInit(const char* input); -void SetTrayImage(void *nsStatusItem, void *imageData, int imageDataLength, int template, int position); int ScalingFactor(void *ctx); diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index f2a847861..cd67014c5 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -295,12 +295,16 @@ void DeleteStatusItem(void *_nsStatusItem) { [nsStatusItem release]; } +void on_main_thread(void (^l)(void)) { + dispatch_async(dispatch_get_main_queue(), l); +} + void SetTrayMenuLabel(void *_nsStatusItem, const char *label) { - ON_MAIN_THREAD( + on_main_thread(^{ NSStatusItem *nsStatusItem = (NSStatusItem*) _nsStatusItem; nsStatusItem.button.title = safeInit(label); - free((void*)label); - ) + free((void*)label); + }); } void SetTrayMenu(void *nsStatusItem, void* nsMenu) { @@ -310,6 +314,16 @@ void SetTrayMenu(void *nsStatusItem, void* nsMenu) { } +/**** Menu Item ****/ + +void SetMenuItemLabel(void *_nsMenuItem, const char *label) { + on_main_thread(^{ + NSMenuItem *nsMenuItem = (NSMenuItem*) _nsMenuItem; + [ nsMenuItem setTitle:safeInit(label) ]; + free((void*)label); + }); +} + void* NewMenu(const char *name) { NSString *title = @""; if (name != nil) { diff --git a/v2/internal/frontend/desktop/darwin/menu.go b/v2/internal/frontend/desktop/darwin/menu.go index 5ab4bed19..f22097b01 100644 --- a/v2/internal/frontend/desktop/darwin/menu.go +++ b/v2/internal/frontend/desktop/darwin/menu.go @@ -131,6 +131,11 @@ func (m *MenuItem) SetChecked(value bool) { C.SetMenuItemChecked(m.nsmenuitem, bool2Cint(value)) } +func (m *MenuItem) SetLabel(label string) { + cLabel := C.CString(label) + C.SetMenuItemLabel(m.nsmenuitem, cLabel) +} + func (m *NSMenu) AddMenuItem(menuItem *menu.MenuItem) *MenuItem { c := NewCalloc() defer c.Free() diff --git a/v2/internal/frontend/devserver/devserver.go b/v2/internal/frontend/devserver/devserver.go index 959811368..356272119 100644 --- a/v2/internal/frontend/devserver/devserver.go +++ b/v2/internal/frontend/devserver/devserver.go @@ -46,6 +46,10 @@ type DevWebServer struct { devServerAddr string } +func (d *DevWebServer) TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl { + return d.desktopFrontend.TrayMenuAdd(trayMenu) +} + func (d *DevWebServer) WindowSetSystemDefaultTheme() { d.desktopFrontend.WindowSetSystemDefaultTheme() } diff --git a/v2/pkg/menu/menu.go b/v2/pkg/menu/menu.go index b5f27c739..c7ad7caf9 100644 --- a/v2/pkg/menu/menu.go +++ b/v2/pkg/menu/menu.go @@ -50,17 +50,17 @@ func (m *Menu) AddSeparator() *MenuItem { return item } -func (m *Menu) AddSubmenu(label string) *Menu { +func (m *Menu) AddSubmenu(label string) *MenuItem { submenu := NewMenu() item := SubMenu(label, submenu) m.Append(item) - return submenu + return item } -func (m *Menu) InsertSubmenu(label string, submenu *Menu) *Menu { +func (m *Menu) InsertSubmenu(label string, submenu *Menu) *MenuItem { item := SubMenu(label, submenu) m.Append(item) - return submenu + return item } func (m *Menu) Prepend(item *MenuItem) { diff --git a/v2/pkg/menu/menuitem.go b/v2/pkg/menu/menuitem.go index 1cefe2259..f5b34dff2 100644 --- a/v2/pkg/menu/menuitem.go +++ b/v2/pkg/menu/menuitem.go @@ -8,6 +8,7 @@ import ( type MenuItemImpl interface { SetChecked(bool) + SetLabel(string) } // MenuItem represents a menuitem contained in a menu @@ -230,6 +231,14 @@ func (m *MenuItem) SetChecked(b bool) { } } +func (m *MenuItem) SetLabel(name string) { + if m.Label == name { + return + } + m.Label = name + m.Impl.SetLabel(name) +} + // Text is a helper to create basic Text menu items func Text(label string, accelerator *keys.Accelerator, click Callback) *MenuItem { return &MenuItem{ From 368733b7cc88412d3332dca653c6d97d9a4d40d5 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 13 May 2022 20:49:54 +1000 Subject: [PATCH 09/48] WIP --- .../frontend/desktop/darwin/traymenu.go | 3 + v2/internal/frontend/desktop/windows/png.go | 36 +++ .../frontend/desktop/windows/traymenu.go | 98 ++++++++ .../frontend/desktop/windows/win32/consts.go | 230 +++++++++++++++++- .../frontend/desktop/windows/win32/tray.go | 130 ++++++++++ website/docs/introduction.mdx | 16 +- website/static/img/varly1.png | Bin 0 -> 224854 bytes 7 files changed, 502 insertions(+), 11 deletions(-) create mode 100644 v2/internal/frontend/desktop/windows/png.go create mode 100644 v2/internal/frontend/desktop/windows/traymenu.go create mode 100644 v2/internal/frontend/desktop/windows/win32/tray.go create mode 100644 website/static/img/varly1.png diff --git a/v2/internal/frontend/desktop/darwin/traymenu.go b/v2/internal/frontend/desktop/darwin/traymenu.go index faf4ec984..6539b359e 100644 --- a/v2/internal/frontend/desktop/darwin/traymenu.go +++ b/v2/internal/frontend/desktop/darwin/traymenu.go @@ -1,3 +1,6 @@ +//go:build darwin +// +build darwin + package darwin /* diff --git a/v2/internal/frontend/desktop/windows/png.go b/v2/internal/frontend/desktop/windows/png.go new file mode 100644 index 000000000..87e7a8d96 --- /dev/null +++ b/v2/internal/frontend/desktop/windows/png.go @@ -0,0 +1,36 @@ +package windows + +import ( + "bufio" + "bytes" + "golang.org/x/image/draw" + "image" + "image/png" +) + +func ResizePNG(in []byte, size int) ([]byte, error) { + imagedata, _, err := image.Decode(bytes.NewReader(in)) + if err != nil { + return nil, err + } + // Scale image + rect := image.Rect(0, 0, size, size) + rawdata := image.NewRGBA(rect) + scale := draw.CatmullRom + scale.Scale(rawdata, rect, imagedata, imagedata.Bounds(), draw.Over, nil) + + // Convert back to PNG + icondata := new(bytes.Buffer) + writer := bufio.NewWriter(icondata) + err = png.Encode(writer, rawdata) + if err != nil { + return nil, err + } + err = writer.Flush() + if err != nil { + return nil, err + } + + // Save image data + return icondata.Bytes(), nil +} diff --git a/v2/internal/frontend/desktop/windows/traymenu.go b/v2/internal/frontend/desktop/windows/traymenu.go new file mode 100644 index 000000000..72c91d7d8 --- /dev/null +++ b/v2/internal/frontend/desktop/windows/traymenu.go @@ -0,0 +1,98 @@ +//go:build windows +// +build windows + +package windows + +import ( + "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32" + "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32" + "github.com/wailsapp/wails/v2/pkg/menu" + "golang.org/x/sys/windows" + "log" + "sync" + "unsafe" +) + +var uids uint32 +var lock sync.RWMutex + +func newUID() uint32 { + lock.Lock() + result := uids + uids++ + lock.Unlock() + return result + +} + +type Win32TrayMenu struct { + hwnd uintptr + uid uint32 + icon uintptr +} + +func (w *Win32TrayMenu) SetLabel(label string) {} + +func (w *Win32TrayMenu) SetMenu(menu *menu.Menu) {} + +func (w *Win32TrayMenu) SetImage(image *menu.TrayImage) { + data := w.newNotifyIconData() + //var iconBuffer bytes.Buffer + //bitmap := image.GetBestBitmap(1, false) + //iconData, err := ResizePNG(bitmap, 32) + //if err != nil { + // log.Fatal(err.Error()) + //} + icon, err := win32.LoadImage( + 0, + windows.StringToUTF16Ptr("icon-44.ico"), + w32.IMAGE_ICON, + 32, + 32, + 0x00000040|0x00000010) + if err != nil && err != windows.ERROR_SUCCESS { + panic(err) + } + data.HIcon = icon + // + //icon, err := win32.CreateIconFromResourceEx(uintptr(unsafe.Pointer(&bitmap[0])), uint32(len(bitmap)), true, 0x30000, 0, 0, 0) + //if err != nil { + // log.Fatal(err.Error()) + //} + data.UFlags |= win32.NIF_ICON + //data.HIcon = icon + if _, err := win32.NotifyIcon(win32.NIM_ADD, data); err != nil { + log.Fatal(err.Error()) + } +} + +func (f *Frontend) NewWin32TrayMenu(trayMenu *menu.TrayMenu) *Win32TrayMenu { + + result := &Win32TrayMenu{ + hwnd: f.mainWindow.Handle(), + uid: newUID(), + } + + data := result.newNotifyIconData() + data.UFlags |= win32.NIF_MESSAGE | win32.NIF_ICON + data.UCallbackMessage = win32.WM_APP + result.uid + if _, err := win32.NotifyIcon(win32.NIM_ADD, data); err != nil { + log.Fatal(err.Error()) + } + + return result +} + +func (w *Win32TrayMenu) newNotifyIconData() *win32.NOTIFYICONDATA { + var data win32.NOTIFYICONDATA + data.CbSize = uint32(unsafe.Sizeof(data)) + data.UFlags = win32.NIF_GUID + data.HWnd = w.hwnd + data.UID = w.uid + return &data +} + +func (f *Frontend) TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl { + win32TrayMenu := f.NewWin32TrayMenu(trayMenu) + return win32TrayMenu +} diff --git a/v2/internal/frontend/desktop/windows/win32/consts.go b/v2/internal/frontend/desktop/windows/win32/consts.go index f84bb43ef..a35465422 100644 --- a/v2/internal/frontend/desktop/windows/win32/consts.go +++ b/v2/internal/frontend/desktop/windows/win32/consts.go @@ -12,9 +12,18 @@ type HRESULT int32 type HANDLE uintptr var ( - moduser32 = syscall.NewLazyDLL("user32.dll") - procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") - procGetWindowLong = moduser32.NewProc("GetWindowLongW") + moduser32 = syscall.NewLazyDLL("user32.dll") + procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") + procGetWindowLong = moduser32.NewProc("GetWindowLongW") + procLookupIconIdFromDirectoryEx = moduser32.NewProc("LookupIconIdFromDirectoryEx") + procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx") + procCreateIconIndirect = moduser32.NewProc("CreateIconIndirect") + procLoadImageW = moduser32.NewProc("LoadImageW") +) + +var ( + modshell32 = syscall.NewLazyDLL("shell32.dll") + procShellNotifyIcon = modshell32.NewProc("Shell_NotifyIconW") ) var ( moddwmapi = syscall.NewLazyDLL("dwmapi.dll") @@ -28,3 +37,218 @@ func IsWindowsVersionAtLeast(major, minor, buildNumber int) bool { windowsVersion.Minor >= minor && windowsVersion.Build >= buildNumber } + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373931.aspx +type GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]byte +} + +const ( + WM_APP = 32768 + WM_ACTIVATE = 6 + WM_ACTIVATEAPP = 28 + WM_AFXFIRST = 864 + WM_AFXLAST = 895 + WM_ASKCBFORMATNAME = 780 + WM_CANCELJOURNAL = 75 + WM_CANCELMODE = 31 + WM_CAPTURECHANGED = 533 + WM_CHANGECBCHAIN = 781 + WM_CHAR = 258 + WM_CHARTOITEM = 47 + WM_CHILDACTIVATE = 34 + WM_CLEAR = 771 + WM_CLOSE = 16 + WM_COMMAND = 273 + WM_COMMNOTIFY = 68 /* OBSOLETE */ + WM_COMPACTING = 65 + WM_COMPAREITEM = 57 + WM_CONTEXTMENU = 123 + WM_COPY = 769 + WM_COPYDATA = 74 + WM_CREATE = 1 + WM_CTLCOLORBTN = 309 + WM_CTLCOLORDLG = 310 + WM_CTLCOLOREDIT = 307 + WM_CTLCOLORLISTBOX = 308 + WM_CTLCOLORMSGBOX = 306 + WM_CTLCOLORSCROLLBAR = 311 + WM_CTLCOLORSTATIC = 312 + WM_CUT = 768 + WM_DEADCHAR = 259 + WM_DELETEITEM = 45 + WM_DESTROY = 2 + WM_DESTROYCLIPBOARD = 775 + WM_DEVICECHANGE = 537 + WM_DEVMODECHANGE = 27 + WM_DISPLAYCHANGE = 126 + WM_DRAWCLIPBOARD = 776 + WM_DRAWITEM = 43 + WM_DROPFILES = 563 + WM_ENABLE = 10 + WM_ENDSESSION = 22 + WM_ENTERIDLE = 289 + WM_ENTERMENULOOP = 529 + WM_ENTERSIZEMOVE = 561 + WM_ERASEBKGND = 20 + WM_EXITMENULOOP = 530 + WM_EXITSIZEMOVE = 562 + WM_FONTCHANGE = 29 + WM_GETDLGCODE = 135 + WM_GETFONT = 49 + WM_GETHOTKEY = 51 + WM_GETICON = 127 + WM_GETMINMAXINFO = 36 + WM_GETTEXT = 13 + WM_GETTEXTLENGTH = 14 + WM_HANDHELDFIRST = 856 + WM_HANDHELDLAST = 863 + WM_HELP = 83 + WM_HOTKEY = 786 + WM_HSCROLL = 276 + WM_HSCROLLCLIPBOARD = 782 + WM_ICONERASEBKGND = 39 + WM_INITDIALOG = 272 + WM_INITMENU = 278 + WM_INITMENUPOPUP = 279 + WM_INPUT = 0x00FF + WM_INPUTLANGCHANGE = 81 + WM_INPUTLANGCHANGEREQUEST = 80 + WM_KEYDOWN = 256 + WM_KEYUP = 257 + WM_KILLFOCUS = 8 + WM_MDIACTIVATE = 546 + WM_MDICASCADE = 551 + WM_MDICREATE = 544 + WM_MDIDESTROY = 545 + WM_MDIGETACTIVE = 553 + WM_MDIICONARRANGE = 552 + WM_MDIMAXIMIZE = 549 + WM_MDINEXT = 548 + WM_MDIREFRESHMENU = 564 + WM_MDIRESTORE = 547 + WM_MDISETMENU = 560 + WM_MDITILE = 550 + WM_MEASUREITEM = 44 + WM_GETOBJECT = 0x003D + WM_CHANGEUISTATE = 0x0127 + WM_UPDATEUISTATE = 0x0128 + WM_QUERYUISTATE = 0x0129 + WM_UNINITMENUPOPUP = 0x0125 + WM_MENURBUTTONUP = 290 + WM_MENUCOMMAND = 0x0126 + WM_MENUGETOBJECT = 0x0124 + WM_MENUDRAG = 0x0123 + WM_APPCOMMAND = 0x0319 + WM_MENUCHAR = 288 + WM_MENUSELECT = 287 + WM_MOVE = 3 + WM_MOVING = 534 + WM_NCACTIVATE = 134 + WM_NCCALCSIZE = 131 + WM_NCCREATE = 129 + WM_NCDESTROY = 130 + WM_NCHITTEST = 132 + WM_NCLBUTTONDBLCLK = 163 + WM_NCLBUTTONDOWN = 161 + WM_NCLBUTTONUP = 162 + WM_NCMBUTTONDBLCLK = 169 + WM_NCMBUTTONDOWN = 167 + WM_NCMBUTTONUP = 168 + WM_NCXBUTTONDOWN = 171 + WM_NCXBUTTONUP = 172 + WM_NCXBUTTONDBLCLK = 173 + WM_NCMOUSEHOVER = 0x02A0 + WM_NCMOUSELEAVE = 0x02A2 + WM_NCMOUSEMOVE = 160 + WM_NCPAINT = 133 + WM_NCRBUTTONDBLCLK = 166 + WM_NCRBUTTONDOWN = 164 + WM_NCRBUTTONUP = 165 + WM_NEXTDLGCTL = 40 + WM_NEXTMENU = 531 + WM_NOTIFY = 78 + WM_NOTIFYFORMAT = 85 + WM_NULL = 0 + WM_PAINT = 15 + WM_PAINTCLIPBOARD = 777 + WM_PAINTICON = 38 + WM_PALETTECHANGED = 785 + WM_PALETTEISCHANGING = 784 + WM_PARENTNOTIFY = 528 + WM_PASTE = 770 + WM_PENWINFIRST = 896 + WM_PENWINLAST = 911 + WM_POWER = 72 + WM_POWERBROADCAST = 536 + WM_PRINT = 791 + WM_PRINTCLIENT = 792 + WM_QUERYDRAGICON = 55 + WM_QUERYENDSESSION = 17 + WM_QUERYNEWPALETTE = 783 + WM_QUERYOPEN = 19 + WM_QUEUESYNC = 35 + WM_QUIT = 18 + WM_RENDERALLFORMATS = 774 + WM_RENDERFORMAT = 773 + WM_SETCURSOR = 32 + WM_SETFOCUS = 7 + WM_SETFONT = 48 + WM_SETHOTKEY = 50 + WM_SETICON = 128 + WM_SETREDRAW = 11 + WM_SETTEXT = 12 + WM_SETTINGCHANGE = 26 + WM_SHOWWINDOW = 24 + WM_SIZE = 5 + WM_SIZECLIPBOARD = 779 + WM_SIZING = 532 + WM_SPOOLERSTATUS = 42 + WM_STYLECHANGED = 125 + WM_STYLECHANGING = 124 + WM_SYSCHAR = 262 + WM_SYSCOLORCHANGE = 21 + WM_SYSCOMMAND = 274 + WM_SYSDEADCHAR = 263 + WM_SYSKEYDOWN = 260 + WM_SYSKEYUP = 261 + WM_TCARD = 82 + WM_THEMECHANGED = 794 + WM_TIMECHANGE = 30 + WM_TIMER = 275 + WM_UNDO = 772 + WM_USER = 1024 + WM_USERCHANGED = 84 + WM_VKEYTOITEM = 46 + WM_VSCROLL = 277 + WM_VSCROLLCLIPBOARD = 778 + WM_WINDOWPOSCHANGED = 71 + WM_WINDOWPOSCHANGING = 70 + WM_WININICHANGE = 26 + WM_KEYFIRST = 256 + WM_KEYLAST = 264 + WM_SYNCPAINT = 136 + WM_MOUSEACTIVATE = 33 + WM_MOUSEMOVE = 512 + WM_LBUTTONDOWN = 513 + WM_LBUTTONUP = 514 + WM_LBUTTONDBLCLK = 515 + WM_RBUTTONDOWN = 516 + WM_RBUTTONUP = 517 + WM_RBUTTONDBLCLK = 518 + WM_MBUTTONDOWN = 519 + WM_MBUTTONUP = 520 + WM_MBUTTONDBLCLK = 521 + WM_MOUSEWHEEL = 522 + WM_MOUSEFIRST = 512 + WM_XBUTTONDOWN = 523 + WM_XBUTTONUP = 524 + WM_XBUTTONDBLCLK = 525 + WM_MOUSELAST = 525 + WM_MOUSEHOVER = 0x2A1 + WM_MOUSELEAVE = 0x2A3 + WM_CLIPBOARDUPDATE = 0x031D +) diff --git a/v2/internal/frontend/desktop/windows/win32/tray.go b/v2/internal/frontend/desktop/windows/win32/tray.go new file mode 100644 index 000000000..897106139 --- /dev/null +++ b/v2/internal/frontend/desktop/windows/win32/tray.go @@ -0,0 +1,130 @@ +package win32 + +import "unsafe" + +const ( + NIF_MESSAGE = 0x00000001 + NIF_ICON = 0x00000002 + NIF_TIP = 0x00000004 + NIF_STATE = 0x00000008 + NIF_INFO = 0x00000010 + NIF_GUID = 0x00000020 + NIF_REALTIME = 0x00000040 + NIF_SHOWTIP = 0x00000080 + NIM_ADD = 0x00000000 + NIM_MODIFY = 0x00000001 + NIM_DELETE = 0x00000002 + NIM_SETFOCUS = 0x00000003 + NIM_SETVERSION = 0x00000004 + NIS_HIDDEN = 0x00000001 + NIS_SHAREDICON = 0x00000002 + NIN_BALLOONSHOW = 0x0402 + NIN_BALLOONTIMEOUT = 0x0404 + NIN_BALLOONUSERCLICK = 0x0405 + NIIF_NONE = 0x00000000 + NIIF_INFO = 0x00000001 + NIIF_WARNING = 0x00000002 + NIIF_ERROR = 0x00000003 + NIIF_USER = 0x00000004 + NIIF_NOSOUND = 0x00000010 + NIIF_LARGE_ICON = 0x00000020 + NIIF_RESPECT_QUIET_TIME = 0x00000080 + NIIF_ICON_MASK = 0x0000000F +) + +type NOTIFYICONDATA struct { + CbSize uint32 + HWnd uintptr + UID uint32 + UFlags uint32 + UCallbackMessage uint32 + HIcon uintptr + SzTip [128]uint16 + DwState uint32 + DwStateMask uint32 + SzInfo [256]uint16 + UVersion uint32 + SzInfoTitle [64]uint16 + DwInfoFlags uint32 + GUIDItem GUID + HBalloonIcon uintptr +} + +func NotifyIcon(msg uint32, lpData *NOTIFYICONDATA) (int32, error) { + r, _, err := procShellNotifyIcon.Call( + uintptr(msg), + uintptr(unsafe.Pointer(lpData))) + if r == 0 { + return 0, err + } + return int32(r), nil +} + +func LookupIconIdFromDirectoryEx(presbits uintptr, isIcon bool, cxDesired int, cyDesired int, flags uint) (int32, error) { + var icon uint32 = 0 + if isIcon { + icon = 1 + } + r, _, err := procLookupIconIdFromDirectoryEx.Call( + presbits, + uintptr(icon), + uintptr(cxDesired), + uintptr(cyDesired), + uintptr(flags), + ) + if r == 0 { + return 0, err + } + return int32(r), nil +} + +func CreateIconIndirect(data uintptr) (uintptr, error) { + r, _, err := procCreateIconIndirect.Call( + data, + ) + + if r == 0 { + return 0, err + } + return r, nil +} + +func CreateIconFromResourceEx(presbits uintptr, dwResSize uint32, isIcon bool, version uint32, cxDesired int, cyDesired int, flags uint) (uintptr, error) { + icon := 0 + if isIcon { + icon = 1 + } + r, _, err := procCreateIconFromResourceEx.Call( + presbits, + uintptr(dwResSize), + uintptr(icon), + uintptr(version), + uintptr(cxDesired), + uintptr(cyDesired), + uintptr(flags), + ) + + if r == 0 { + return 0, err + } + return r, nil +} + +func LoadImage( + hInst uintptr, + name *uint16, + type_ uint32, + cx, cy int32, + fuLoad uint32) (uintptr, error) { + r, _, err := procLoadImageW.Call( + hInst, + uintptr(unsafe.Pointer(name)), + uintptr(type_), + uintptr(cx), + uintptr(cy), + uintptr(fuLoad)) + if r == 0 { + return 0, err + } + return r, nil +} diff --git a/website/docs/introduction.mdx b/website/docs/introduction.mdx index 846b21e1d..dbbd0884c 100644 --- a/website/docs/introduction.mdx +++ b/website/docs/introduction.mdx @@ -6,19 +6,19 @@ sidebar_position: 1 ## Overview -Wails is a project that enables you to write desktop apps using Go and web technologies. +Wails is a toolkit that enables you to write beautiful desktop apps using Go. Consider it a lightweight and fast Electron alternative for Go. You can easily build applications with the flexibility -and power of Go, combined with a rich, modern frontend. +and power of Go, with modern frontend technology. -Wails doesn't hold back with the eye candy either! This is [xbar](https://xbarapp.com) - a desktop application for MacOS -written using Wails. It has menus, supports light and dark desktop themes, and the main window uses translucency that -gives it that 'frosty' effect of a native app. +Wails also offers out-of-the-box integration with the native system libraries, providing native menus, dialogs, +windowing functions, as well as dark and light themes. It also provides a simple way to use native window translucency, +allowing you to create modern, beautiful applications.

- - - + + +

## Quick Start Templates diff --git a/website/static/img/varly1.png b/website/static/img/varly1.png new file mode 100644 index 0000000000000000000000000000000000000000..0dac80579c4c38395e3496b4ed0ba9d13fa29ea5 GIT binary patch literal 224854 zcmXt8dpuMB|6i$8LQ*cdRpul2ba5RjMN7FhVQz&8bIoNl6DrCrb1#=7(Ol*_av2hH z%iM3nsKtlj%3;@jm-~a#|1c1W;a2x;$03bmCBn*JWIgAA0KmZ&J zfW!G;NB{%~zyJXpAP@iqLV!RF5Xb?70YESW2*v=x93Tt;gh7BX3=qZvq5(iO1c=4} z(HtNS0K`FnI1CWS0g?bf5(G%X07;y~)d4vWAO{2FaQ?SU00a!cfB_sZ5C8^3z(5Qb z$N_@^U@!y>#(=>bFbn{OLBKE!7{&pk0bn!)jK+Y`954<5#zDY13>e1&lK@~61Wdw! zNu0wSgEwHmg8^tT1P#WZ!5lOUfQCWPFbo>TL8Ad^Gz5*tpwS#O4uHl%&^Qbl z$3c?-Xc7cX!k|ffQ0XQ%O2gcyQ z92^XQgF$dG3=YP@p#eBF1c%1p&>S2NfWtv>I1CQQ!I1zs5(G!W;7FXqYU4N%90!Br zaQ;_z0E7go#*n}q5)43sK}awR3C1Cz0VFhpgvOB2 z91;#d!a+zl3<<{}kpLtTghaxSNSs3ikvI?%2Seg;{s$!hgag1FqUsP#93X@P#2g~v zu<#r(gagJLR_m}x92kTH!yIPzFrgeYgoDN$X5n!292|s$!yK;oaG@L$ghRp{Mn4S7 z;XpVX%;DY2XD{W$FW{8V18aW(Ky>7P*AbEauJyy0+^@io?{hC6=Q*u#)eiB22LQMP z0N=awBsg=eu_=C`qg)m#d3!PR_44iN@^;q_Yujf^C;AkJZXic4_Z65OMMyr63m>T+ zU3z-<%TM75=Z?P6H)``IrQW2dnp`?F|EK2cC8zC=J$eF7u^o@H{V_##QD^Smf3epM z%!qP+axEz;9Q*E>hOXeX1kix!NRw-=EW`u}ag`x<7*Bmah6o5l{!>uhpd8$gLCw2> zT8qOQQcl?Ji0>!{hv!_4w0}GB7I9LN>=7veEege|s2nMyR_prRCrl7Od1JF|cD2{a zTK!wXqu#?cHg6XDC=-*N;3-)V=a-8GR}1DggWI2J4a)Tm`hM6FnKvxtX5AHz-E*2X ziOI=Z$T0zB*X(X)Qz=azntjogp7W1{b$P_q2kNGN8oGY_rq2ABG8M6DjMU@UF&=H~ z)Exh>P|T0-oN+)rlburIlZ)?zW?!&kfs_41ooB*rcNF%4U3}y|X+Hdm!sYz^3kRd< zCH@}=`Pb8u$G64cYs(KY?4xzjd9B!$k7foR*r}PPHG@{n)Pw6%$sS*EScU7^+Pz{w zlWjF2TdC*b-&;v4HGMtS#8niFsxf~)-*<| znqzsFn&h97v=vp?fV1PBx8M2wP|w_~{c^-GD#tN$N?=7i*YUlyX{@2)4a=07P0^jD zDEYlq&pXD+TnStWDaOe$wKn6vWl&;pscV+$Q|V()F413O%(PM)E(WtJru=TMrk0=@ zZZ?M|f`kGlr98-r4%KsIDNU^uE~HbV2dObYTkpO`Px(L1_63VCMj-7`eQ|NOd44lK z##t^C!ddJI(0fEI%xO*gr^bbbTZ?~C#)O)2?wnU=#FrYQ;R4@KJmzbP&tJxd#^9VA zB<5yr{ku@^6&uOpPG<3-6x4eCVqHUCD+F%-AdLP6uC|n$6Q|kxKhlvNdL7Y3X)+@U zsl1QT3Yt(g#o9%ot6c3-be%wV`pVpjSyd(O2-u z%ceP)`t1~dJib2uEo=UkI*31B=eQl3ea$|Xug1+I6N2I%@$MKPY@&Azno?}nq9($e zI47M4jJw7PokETUzR<4F^CT%PwDS5ji=I$PZM@*PCpJqtYkhZ`X`gJUXviZOLTk)G zW0G2len(lXLW=E8f>w&wMSWW_dVM#fxr2cz(jUUw-giHb)g8IeF-ST(kOsl+*@Uhv zM^T7_Q*}~8>xtI8HY85=oKH+B`_xgptE6X9JTqtg8jK{a@H12ku?U`7uwZf1WP| zoG{-P*cIRZjS}#XxSqY5WV;nE8hj#E%XumBjt9bWN}*;8`g*(3=l$aZlW!~${~3=D zes?Z=RqUs*ZHR8%gb#oD31ZMWzE=z0a^oNDorefHDcKsS?wq%eX(nuq3%eJJ4W>{u z;V{CO)G&U_Ig3)Eqa>?8N`o|i?O;4i2Z(O&A@dmT$fu`zxzKeXS*@g)DgFQt(t*LHhTI1HuOW`3`gx|*QXMX<#`<_o?SZ1Ram?UJoR;ZfVRhDbnqwJt>@#k#{nGX3(4$H`oJk@(XA^KW&cQD($S?C{UO+yOeD zZ9+zyZ{f#UQf*f*SI4)OY%?uUfn(32lze8AIZAV50g@YR<(u}tBa?IR9${=p50+DEe8W*`4esMmJePXoaxnIoGd?RCD^jPAupL; zc)N#xvHxSjuY>C|3TsxNm*?Tn2X2ll5m7kt93#WR(Y;+bRA16}`TO#8?u_Z>%LbRjmT&x%qHSf>S&}23Y=&Pym0EgyEms4X^pBx1$v|A$ijL0#ZBJ~9^LP7 zd=f$yF~FMKihmV?-$(6bYA3v>fJGdW4oR7i*}swe?Tt`jr0(S9IWC3ZF`uKYT|#a~#CsYIoeFT$Lxd48skDDBAlQ&ao8F%j zBb-lwO$J#@S+{Mz=pW%B>UiRzaRWv! zzpliAou~w6MHKtv69O-Fe}Z+HgN230dG{9(5qOe@OhR!_ zD!83O3ja3km!_U)$&JSLUjH+SBXN?(bKp|D<8X36MrF&+K{tI)yPw(v@{9lK6q_;Y zDC8^KBM`rr%}m$(Gtoyo)%u}TNVmnm=u6(vea+RnH>DKMLH_!K;rf{D$pI|u@(KK~ zE=9NdpnLz)S22c?{DS#^FmM$(52x?&^HIh{HJNkCFC)GFWWRQ85rP{r)l4(7i7-4^ zd#hcERz^1PB;?xC6I^cLEOgwZd5o$)8Pa4`Bp+w%Bw#4P#>edqT z>*n4j(SN}6lNq3yXo3HtUnuDijh*5>ysIr!(^Pb8(x{S`IU&@A@YbMn8}Wm6(icGM zgCE}R(p%i}KI)^?(_(_PV%dInFNFd{pcIYqUO~g%OxbrxAK1++kOTEE43Dyj>h?ND zcbRjl{U6+70VOzi*OkTCt{E9gJs90ywUN@cJ%M!6d(apNYP95d4U=pGg&IGyt^U>tDDt(_HTueFDLyKFdA*VK3raZ!-CSzy#I}`WpV@b`?y6oJ znnIO0+U{7OG!i@Q^6>h2jkE0Y zbZ6le;M(($iqI0*CE3#af?MZ!_aUM2pA~tm2bS{(9N@~kZgU{vx#oU<-y*!H;7W)0 zc*eFOA=W!;F42*5%565`9mh=t*yej?4|p?ZisGm@ zbt{fW8k0}((L945vF4pB1Za$Uu>PLGxzd2Q@Tup2+=B2_?F%N%`It27(a+?&=Dy`O z3TmS5cpDGWQ?s=4Vm+Z5SeLRSV%&X@;j-rQ6oI9W`<~i1c+;GX@#OJPoF!79SnzF2 zDeM`Ur|Au&*LCYvR2#*=C5CoylVz_HnRL~IV?(@4u&mY(t$Ul(=Y&;v!%DHjd(lx&^~ni(1Jgy8G{pB}1z0sh=~kb;<$e z&=33??t1zB^Iz>BzhHDq7{Vnt=I6s?xvQu9Ixh3OdtI9kj{*HFS5~LtE#uRz3E5`} z=J0~$qw?-JS?nKMLb|A5skPERb2@=>y34Bm95xRm3 z>-919N5|U2c5(9~#>XW%IuFOs?i_UBHD;>yCO?K66bzeH`ruh~p zfA%fQTgAaPMCP-pFr?Z-BKcQfSgzC-;e~ddM-&1V`on=)X-ltLul-LpOE3j>KkH1r zl`KT|LcyB>cWi_Cj9KaDP5uB=^8-`m-Ncs@^{eWj-ZHzPcR~M3)Uteyh4>jdAz1#g zG}Ro1!7y=YbFcNheyQs#9Gl z+G-1@KYkgAmpCwg(IU9eLGjUf4B{Feb-5E)WKt!o^Q)^U`G%B6>Zz{6Q7&tTIIns= z1Bu;v#^5T{TQ7u}Kcc)6yk`?u5{kdaN!@L1<p)*D;7BrfRz3dYWc2ijT=XLyF^aX zeieGRdcHUm>NhXzT);1`hWzK+n)5NKFQ(4DDZdBtotsmU1KdrS$aU2Jm7R=w?@SvX zN?{v_eOEa~6bk59NyQ$iZ>%M<9?(vpuni#GTibSrYv1#1$DvLd>_}P#_PS&hDy*2) zxzB6ZB@$`bG*E85f5k#F;gf3t>!`teomJtf-5D@3$W#t3B9Num+- zPwDyG%f_yRzbkq|n;txfSKpM``6nv$g`M@iC0w-PCG`(1CrYFV1&s*!JyAAr*6Y^n zhR)hMi2_YIA+pGL-eTfM)ghgXdz{N-m(+wC_{wXThb%_GmA&#loz+zJ8Hz;TcdHktl7K`(f#a9=GR6f z_3GjQ22_?VRy>mW?q{o0I*;OL+e7MOy0*a6g6l=;Kec3cvIO*qG{K;@U;k<%#aJ_^ z%kBsmUS;m!)(}gUYs+*QMA|mpX5TUl<{V>^g|kjLlk=uLCARb03FykVRq>S@yz2t4 zjcz$B6?(<%{Zg`;%Yl8$BQ9Z1Qgf*HbrWGxWDlx2C`buqL>0WOxqfa$%;`JSWu*+xQmbobMTVM;}#{6q;vpOvbDUsXQ!>RL3S*+L((U^*>-C8SOy}q`l z?D^C!Cfc{UFKZX2tDD-dN9Q#bSN2javYy=_L*FZuXqlUMZED)J72cNLVxK)issxbe zuRs|=pfZQFwI~-dsmU@2x{ECN$EUs47ooqC0z@X0XZ3ag@}I!YHL0D#(ZuWl=9>lNoTl=qYFWHd3CO3H8UJ6XD`{mI2l@9 zZ{o%sPLMO!kB4qxoaKRlk%+o!h8%Q>#6AO*G9nv86A-{4DZ_L$*U7j4!-HMqf%g-i{)lm)@@zdWSu>a*3ncmZg@7n;Pb*~e9F*=ARX2(;isHT{ug(^?cYWZ=@!c# z%S&wcNO(R8`mk60F=Nkc!Rfwz8c@&l9OI_nZ>>J7r_#Z(7bl1noyhB}6+P7LE8$We zLm@6lr6jAIp=@~PLE>Km4MJ*~X5S(_k22w!oM8^6a_sBvo3x!Z9;Fkj=`Hd^?e_t> z!!-$tdM?UVq0pD%H*-d9Wf33!kuuGQzGbM9_bB5VcNR}PRbQAMx?t1qzE26d`<(;1}shKr@8dVkhbJ{Y7 ze1TtVeXD&8Cl%=2L2<9olO_a$@HJs5Jx`m(sW&>J<$|J!iR|+^HVFD~du;#JDnq$= zFk4a1RVN?IGFR#L+kMg@lhQ2Hu3_{$M6tV~bbB*`*Xf~={a}lKcqqLcCoM~qWMwyu zd~eMm0mpU!1q~$)Eeoq=6a2#Zb>oD`!l=wE`(4`~$SFhPsa&|HaQwY6D`&H52H#e> z0GB$wW$@UVH>Q$S7XBffUU_lDIEn@tawKRbTI`E?5A0+}m*^)A1r zo+7=)+eKNUL{I`oE~P#shMuC{6J|O1>rh0fcq2GDq)pf#Wnpi%LRKLgUiZh#31@a? zj<&PU`;6BlKFPY7b6jdpjaa%0PZwWVKJE}G)>~ORDhZi~nz8)0tNRv;P0kDKyunH&`>|Y))|I(jy=xhLF>>FYSKv8?(J1oq3(skr;B@ z(WBEe%5Tqh@)Vb=Xu`8&-^R4uI&6JX6JpE#J?yVNmv+e9FJCuYe7o)t4c#_qWb)iu zJH8cj9qUlCU2+h-e-}>0dyW$&viXCh!-|@w5h`R4VxIPxk0~9=K-%f(X;6YS=Oe5a zeedg9VY!uPO%{*w?agvIF)X`ul~{VXZ|IWKLVfF%6F6Ekg4Zo>L3}povNwnlLw+CY z)3=bWV(F_&{!D$)B&b@!P$H)br#1u?=SWPSlBak5yI~;g7#o8ex`Rq+9FBK!Wwi#A zFb){%Gn258CCjk1l^UNS6t{Vbo%GO5 zeZiq5&@8?9IIOi#ifVuS5a;SQCpKlpkS71kx((_=r#+gL4aT9)@E$FfZ_SDl9D%;w?U zNFStL9j=$&*h)P{egEstn!4`X1^T-m$=#F(o1nxM$qrX=v3F;a5H2-qA>lTD(pS9R zy4@h7#bojUi1`pzl=C+GS<-}4i3-Vly>eRb+zViU)rx6pCC)DKOlXxVGW~jYDK}_J zN!JEnZZcc@!D-pdtD{rffj4v^=;q#WUFe>h)4p1>L$RUM2=y*5e>W*XG zeDq5AE&D%~o3&m>UkHEk`iTZ1mK`5*=G^%}nwaNnww>HX0#V3hLcd;W(@_YM)+3Q8 z>0+B`9q2ZQ9^Heg**lb=h9^o{WqZTyD1;S`9dK&0i)a)DrOI-_sz=?M76|lF5(+yt zauC{iwuxJu!e|f3WC1BFsdQwF_sQ1o4o?IcE1X*lI_P=$uWn=5wCC)(!@bg2|EynCT`ty zB+$)>m=qJ(@liHoN$rR4QMPBM*tifa*JR`Kgqqqs0pTu4n6qLhR1A$$dXJ>_Z?JV= z$t;$%)qb9toIpIzEjJbb{hSx{I0X(3M9%7bt;M-w{om6#K?_T*0pI44&*m_BwBHvV z8cT%VDezQ}b7Zf6{E`JhZ>EX1iZ&F;#iHq>b*W^Evf@6vyY3IBk+F zS8_ay!ubv=i;d(?rGg6Jcu_0DFRlp+^Lt5yPcOgls(utzq7&p38@IqFTCjC}_EO6- zpMtu&=tnJ$`Uu`YGla;!B zJHA+m-Eg#s6?F0xKFEMTSJLAznXrL{V3L zgn_T02w9i3s#n}r$MeG0r5D4vFFTCB$8R*c#U@SFjz=4Weo>fr?&$n_$$>3mkQ84c z>h~)XUY_0MB=29?z31IvUkfL17`Vc2q9dG9rDjjABOZ0?3JRz-T9P(i7W{8kD3)=X5;{vU85%C1~l=StB!3lUK0;r~Mu>hE?(@^}|xf!^WNFlW46o z*tMJ$`iY0Pm2}XAccG1c&J!aE*eq;;B)=c0aZYJ#-ZyjMJ8VW!8zs^kHT(|bowENi z^oo#L?jzfHib*op_Q)Ga`HEWmEr_qT@S|4b87|W~`$~v${F`6Z@gktIF9uC-bZvj6 zt{T*B_nf=vD|rp8C2eT;?5XYBhKBNT3#q5zmAE%jUYd?$&V)PqCVJGO-D8>jj61$W$}L}(IEscq4B`}*UD)f0^0lGmER zf9so{$6qTI&Ke1AM^Z^L4w?9pn;q1XDrA29#pA2UQd^Gbj~)g-lJ)DZ?mI@7{`Au( zt~d|-;l86L@2J`iHFY;Z+~Xs7PzXq%!Q7LMC2tkADrIVEOTD#v6o_Fgfu1ANvl zLzId~BXm@<>Kb&22a2xT7U=$cLS9#fQ;NFKDFpesv6#!LqKmjqJQ#6bDgz-Fw#gx{A2dFdj+WZrJ=i zVz+qZ(ia`J^H@+#+T8SWyh>Dvpo@--u!|+__W0kYVZ1ohmW*mIkLAHE^|x2vJNQuL z>|bo|lJ{Vax4)g9O6AvgFe=JAbooe;ly-8ndIfofo6(5Ca#B%6`06G-8IAd|Ta=)J zBb4JY0Tmh#WrK8ta`cQ%l&$Jnl5P0XG)>8 ze?RiGm7eHg&T93cRTdBYhC&Ekx=m02sGi`f6Lt3(Tjt*FJ;eQ6+p?*ud~Li5 zQCrZ&3%c`~)xp_o=hhf4@u(R72Zhw}gxPda-BYZ?zgj?TRo=thegpF#CV3(z&q1JF zkfYeUd;ZJlwSRAaI!1Wtj)Y#yS6Pp~rKD&bvbmMpj(8{6_VI?fi2nJ~$mCLs1&GWT zR|29?)mxt4qP#YV7qC#5BrgH*R4%a3Y;qzBqU^hCK1qD2Qik#hX!oDAnB4 z@X019_%+D=OJ23j_dZUj{(PC-EmE^mYlRnv-3iEAIzG?t6)YB%7;Sh+=GFZGq6!=y z#5kYHN%oe2%Ecpd$eAEb?pS2HtT@>LFSSWB^tIpUU^lu@wI5VZmbwf^;EWL`zNEfj ziC=Nj+Ip`l)n)4aY6tS|0>R3_+C+j?ty_geG#nlO;<<`$F07vvxSvr%3EBi18`ypf z9*An=k`j0-VcrmX>{U!`rj};I#VvLjd|AUYU)ogT#Y697nj`)E?bahZG1q%t{2OkN zoJ4k=VpXm?KU5~j^GJ;BV~2U35KS+d10$!1DBW(vl_?F*eGcg8XdU(_myaQ?u^p~_IM2|2OAg{(wgDBmO_mID9n zR9gS)=8iOEZJ;9};A_cV>6EhnO3`nzKRgDyU5a)_CVBnjn6fPk@0zfjAFZm-HCx(`CHr1>pd611X6c4KeeXd>Qm0tWPV>IK!Z}xX z5waun*V1iP*1z^$OvKp-{EQ?yLmlFQT;W@t>)4!IjW)YAD`6#674DxVQ9?TM>o2Sk zH39iOU-26nw*49ebNT;Hv-7G1Z*IyBr>HCt#${)cTB+64?|Dnm1ajItgQh|=?6a@k zpAsl8x?awmo3$9#t`$4)a{)inoHNzO4|s@2oM7~ZnV6Z$b3x>gj;~i$R&DMYe0EdV z5#O525E@Otd6$OhXRRcY4SW5J5k0e*WJ6v#R2J}$f7Q)kP%WQ<%>G;s((Xd{!$p`ohxLB%jC5FnSqNSOG9FZ`&#$isU^Lr8n zQ|aOQYZn)aDaXa4SMSa3{;_Sxz7Y4=&>2%RsbzWI#VLygbgS!+V?wNk^LTQIFGKXa zgt&*;CblDT16DX>B~IqOBGP|3NlDWw>%7BuR7y{O(q8|748fA7Bhj6f?|mfZ98Xu8 zMRZ(ooPn9B-K_xBX*;Ke^ttXqfdd~~0c~7`U9Z}2(HO0$IrsQG;=;#h$bWsh(8xwj zd~tci&|pi2`a8672A9Fb?pvB-*W)5v6zDAz*dFfHTe;X+-)!?FkCjQs9XyCbga71iePl0b#kS& z$A-VShTkN1Y}7^y8fs8j?Xrw>)-G92G` z1EE*1(7cCxM-H~ORp>t_sMm2neuLiW31wcNR^9)&P*Wusa2kRxe>!WRdFOFopI4O; zxi(aDZ>|s5y(fJf^fOGAnZLA+-{DD;6Ulm(M4z#^}d-(NHloN z6Y_4;a-6y(RW4F@^VEWDhn;_URP!~W}C zcl<{lZBnvX9|}gJEeu7~UxDyaSHVKN) zIi{;1r|XkC_Sskce?61*?m0q%w>{JKwiVVIays*8fr(O*r**tM@OdM+7-LOnkyR#F z;&PN~XOgd4De2^pp8C;j$Q#o}w0LA^fJdYZzBWBX-6N4gtHpx-N{Muy8UsNF+G{-&g zS%V7$)7{csIxEQ19m$PDxMP$Tk9T{YE`t9y3bp5XgrwALXU*84c65umB}Qu>s(Q8y z&})^%#}Arzz#WLucd32l#;+EBghO#hl|t3F)O4gQphSjAD6Qaw^rzjDH7nE7r6{G; z#Ot7LS@>0#-<|$rS*fqVJv(?qx{YDi)gpcG zYM>Mw1-8=vsJ6{O$19Z!4m$QlZr#_pxQckgaOS6Y-V0sLT%;4vsguF6^Z#WX^yhfc|9CA|(0rUMUhyFeaLak9?~WZ-nUuS+n=ZGY zCFlwlc?oUekEOr%eNsR!o{!-rsbU{4sJyLx;p*s}JvKz2Sn}KzymSP%d~WGnhhk_I zY_nzs8Q(XdViJ$UPUmKmQxEdj?Iv<0u8aSdRlgv<`iUM&R}bgb@fM-*7p0F`t82CW zzT)kP(yL98;-iPt8>aI*<|Mg0R{69J<-@Ri*nrsLBOe`Z&k|mV(buT~9#fQPrZ37T zQzdheH^FxCkU$(aY;I7YnNkA}89j5UgmLX(!*4I1^-Zz_zwq|t#}JfgA)#gg78Z_f zbB)4of!q9!`Ta25#72ij7_g1L0vV@Pez=a6P8v9iXqgfFZiR{v3O3eRw7uey zDeg{wc`@Z>^0D=6w1M6K&SOnkp{X}5G-5yQO#S^G_i@!vLf%~3B+kCzU)-a=A3l(8^mmP#O37-keFeGNKgg=!28I&@eGiGRPzAN)N0P%Nc2sB#qOb#<|t z(^tYi&)Nnqo~o>%)0;i%39OKo&H5(7S^DhW42Z)lu`=SJw^?+Fsip)YAp0Yr1~JyHFtH2m4;x>M z4*Wc^u3J7Ljcv-euYCMN-s23lByV{tYM%PwxLLEK zz!*CC5c+`9k`%+sdaE-e8h;~OU6S|1T;Rh-O1qVv@(H@QFTd|oxXHnzaB3-bVn5`IJtb36d8! zN5WI1mdsesqAI}dO$#;g+8(OM%(sxnMMCcNf4%gOLG4~kyn1_+_aEwsIc7vcMX#(s zubV7KjKc9_3;9HcQT=1r79+!n?<6Tm8hFE1qx?Jbk_qd1pVT<6hDz;VW^;qIJylk7 z9%*j{#bt^Gijcfg9P}FxY{pi|mZ3!aYz|`0414?f^J}xVmURv6yuy6X*DAQN6Kz!Q z?~_LEFqTn2|8GBxill@#qcq=MyMq&3E+Tl#*{k$c)b*p|(@#>cSyRWtfH6B9QE-VkmPEjKa@|0^FCY6}1RfWBvM%h5!ws+ZD>m&-f2 zTG<1KPAl@zixkeERhzhU<}mATKuOV_#J645MZdqh&Fqktycz!t9?73Q+@sA0WX+(Z z=-q}@{oM8X(AfGP#V^PcG^ilfs|F1HqQjH(T$;O5 z>NL)IX*l@F-$b+R6-(_xVubYeaGsOC@^Wxvqk3wdWH&tyk!vqONey!?7Dz4GPjTX7 zTP>Xmso3**{~`qJmE{eh>NvIPdwYIz2~l#h&N=pc>TY+cwr251puU26{AK?L? zR)RYnpO#o^11u;6!4o2PrQ*sCDog!m{S$@bH7X?GVDld^{H|7?+x(EI#x z%Hc_;cl9V)3i}6o`Hq;Sgv-fPr7jWY2mLv+yXOE*k5!akYiS!bC4{ZiSn|q)14R&z zn~djh^>A7GF8+x2kc|x=FDI~C`VIcjs~4HyahLGbi`+5DiXN`01}fBwu2~98IkcD@ zPLyfT!$WYka3)@(2lY?5d)3xaRV6qD%lf;)w-t)uXwt}UHO6f?<7~dN+`rR^&Wlzx z5%JYkS~}%<340#P7OWC8m67{D3#cU3B_CJ4v3^$z`)zD#!H#p=i+3O|=if2nr62p_ zHKY@)jll_*rgJMom-Tm^Et!~+E8w_W2PbKgQX}wk&l2B-&5*K%!HEJ%9gmzlsqHD! z4(*-k1dHDqsM!~BM&|;Kh7L<9?;F~+g=rqTq+FK7M{{3YdzHH=IFE`M3w}Olevf=BcZ6RDppT7d#L3=ir=F<9ZFF zLk>zv0U+({N|$XA)qdkKy0t@IQ4)Ahjo&{TY8mn^at_pqoO&EYv_IMtBF z=g&62RsbrGWd37@Ls#_^Br2eKqMqI{Up?Cp(nBH7J1oVmlVoiFeSGZ$HwQATD`|v zd!((z*At;k21u0FnHbVn#MC^hy=4;yUFcx4=NL7^hg0|IgPJY;D~)JYZChP$8^{rA zLUA$L7iZ$uGLha?kYk(5BGbk{G$6jVGzhe~M;lU?4GztL+mWm{=W4>~>^_s4 z;}J9c=cDqr$-bX5>56`WGw9|~yVw4pjFB53@EsF5?2CO5@*9G2uhx_rFOu_=)($Oq zg}uCK6wFIOVnN>A=CH`kcUq-i%gbpJGH#+}*_2RYhGYTvELjgF<>aK6t`t(tCOkOrp9ylGOT1cud z2KfI=Z>#H5oE-=8TOCrZ)TTD(XaCQP25bs<>Z%5X)wBru8!ac9{lHotM@p3G+bSBYI7(p={%k z84{wzg`qx(%edE7L05?iwh;B(k^@cj)dh5GlMLEI_9Gl2foePW`O357xQjJ*tbDi> zncGGeW%xFL?Yu#!vwkHwsqFsP<|Qcplie5;Iln8q`o3a2l9rogmeBMI`wR5KYPiu? zh9E2oQhRk8s(mzD9&R~r(rl;`xYfmWoJeCw%2OJ!v0jJ9Vq!M!$AOSns#_%rEE3qcV# z-rf2Zb^PyP($^@F_r=Bin_o^JN-1p((_1=@as*b>kKS$MOoz#}m5>c>h{Io6?f3^_ zy*9c5g&tiLB-d0krIcL1;JFeKz;8&9(p5+~FwMCkqkx-ukhWTa31Od?2Tt?!?01;I zG*ncw9?MvF%)rhtmp&1H6ep`4Z~g=wxzgy;J{lQphq!Wy^DrmCs>AAK#hy{3aJyK^s5+nSq?sV2 zurNu|`r7jlHSv_TlT%llgj6=eeu^h}%$r5^prKm7>q<&Y=^;gd%FCmC+Q*|Yv%rS)kp;7#n>7g`X!6N-L8-FQ@9Rgy)xKQTdq>?>hELCZBH7Vezh=`~lD=P2 z$y{HUu(Igkr+4f=lebHhDxyWrUdY#H0ZHc zE%WEM*cMM4{jFgqN~aQjm`F*Go2P5&e%5zL)wT^@ybDEd0xA)B6TIebbda-m&P&Ar z3%iD(o-=-2qjGjna82ls4uiqk^fQ>_#7;Mvn(ij8}o4BP=Z!pwmQC{ zTzUU&o{|jN^3bek!ahfl8~6Q@w%55mc2OncKh~Itt48+YoDmJWW51mAOy^fC+?H89 zPRK_0I-dbvV-fD6vvTG*D&lH-j>hSKZ$w6Cb^2kY-G0nD*W_jrVQ5;jg;>bp+1kz$ zV~=(<9((paTk0uXOhgouc^m7Wl z0Qa@0f*Z)5e+0J|xpSU<`pran&?ANseP>vIccvVT5kI_;vgwCvP@DGfd%cPdE<;qI zp?ttcau9JepqnG4C%fUKXS9Pd{(j(ZI$apWwhvVx4~D2dxN^cTvC?=%W<&pB5WY)g zuR3{kBkQa=RkGB!$fO@X=1$CTl1*Vtcf>iBgQo{p7xdYXUYSE|2ca7jVH7sFm8%ZvU#09Bj94DG59 z^QV@R`;%_C6H7d!by! z=xW-oYo_<&0NLih1%5^@XgR^gawWuxc+q4e-N@(cPl$5YxsQ}(>jQT!A@};dMlwYA zJkpv-=1wh~8=hul>y(X*e|iU0uMMJXLz<^C!c{iF3SpMxFWDk&{?o z{qF7B?$S|meibu#lC9Br=)}98qwswACOPOeA~tOSIdhrF^CC-163w}@WYiR4Y^o

YdBRd-0h^rA%F9{TH8hWNeR5=nyTZ(E9o9v6X>S)%R&85Q^UN5ADGbZ{v z5*T7gnObdKRH=xSy%Ho#r0Um&Yq6=SOVI*%;ZNEUufIS^hJ1VF^Tg(}NX8HTC;ie_ zpYB1{&+4Ea7ZAQ1Hq9H|mJBle*H;ui`n`Z8&#Vf1?|H~>A88c(%JOGYb}$Xt9v+H# z$p>iE$DGGxj*Ct~ZLCL3b@2y~@3HdlTlw@z!DKS$0v&EK9rXTX9IM4$vb;Qd>!N;T z7PT>m*6cB_uz0G#N{HTkTeH1hQw4dN`9y^ia&BRj_G_|`Ikw~)ftQW_q^s-k1^?8r zY745SgUUJavqXQxme@`Qi4wO5)K!;GA4FL8T$+g2y023!)35yVf$4W+&6W3of7JRC z#=?9brB_SAGciL0Nd&uWXluMUek;l;@{Ikn1gA?Y%~s~@_F!NiB+zg2iyn?xf6=vH z*$qnDic{!IYT~k%O}=5u`lFbtHWHloLA;x1o_fSEUEDpT-;$=(1pPm%-aH=aHT)kw zQmG@R)e>e-Nh)i~K1>~zQ$mgk*-2tBc7|CtW<-+0kbRp`Vq_a4Bimpw7!1Z3 zW433`_xt-j&+EBgpMO8E*L`32b-(XxdtdiJ-C*N%i)M|>v8X3I_6X3AByUO63fW0n zarQ)#sjeL1#L>&?)tYfGWtUI`ow{=Ud95 z2i5hw+R%WcBVfD=ot0SE#cbQ$$XhQRXG{vqqcA8DyUl2o@lIYuepBuTnFgSY7j zCY~5kx}Ra+4VF#VmNP>N%LFoEM_aW2)ei4de%^l1;?B~&RD+uqp!tQRsO`N7>k<_vZ+J|@ z-zNl%I8z{E$lSS3expobl8d}!i-$bfDqpSr(GefN#$I5fsVD>Hl(}5kj2GiL%uP+#`fXJ&ExtYSCV4shzCwl8q9Y8e zo~xRo^v`B?Gc}e|;r7d6M9RfoYi&UW>p(v|>SrDt`LOFHEgde9%8M;DE7K2Te{*u>$3=?g$*LC_0MTheNx zElPIbATEfd4*ANPvA3>TyvK|-p1#Sewl&9llcBJViq@$6uIkZ3IB_9**Rg7z0!ve9 z@>@@rkG=9qSba5cX1KkN>iQ|6sn&aBEJUl@ zYm(}Jy@w{#oU;0+@(pbt@$SV(l_mve!t#P{eA7Q@>_zf@I$tHx(7njal~8=wE4cMA zo&9TTsk+Vjjl>%JM?A`K?J^8_Vq^DVXHL}KS0|l|!y8XT$@-l+7q;18W+nYVhs1bs zJn|t>wbYxe61jW#T?RG>Popfysfhee$;{D~P`3h6RZlw)@+K}*1g5wMwhHGKg1Z64h7%**pXOs7St`fWM?z#M+s>QKu%wptGvu^RR)N`6BvQht zU&6(%<5RgXZPCdbJ8~t9R7jJs)-=((6h4(m%<45u=NU6p6d-a`h>$dCVL32B=nmQVSI^72~lR^N*_LIkYcjZp# zEGE46#LF%3BJO;3jXZs0(6guT;o_NrBkN}d;(io7KV%x^S68t8irMNl&Kdt&Tl?-5 zVZ3W&doIcK7I5@a0!2)o>?g|NX|HF+Sg*lu3&YR%WGm%@Kd^4p5e7v*pIrJ-I(X4G z=)^J8VO-N$MhDanBK6uv_2sDoOtI&Z)GX5sE2vhDGcY z{|!Zadw^@Dt!8vQ>JVpimizT3U>h%)jJo531+8q@sv8$)h5IhVN*XSptNp;g@KWlO zlt<1W;&CBH`KPT5+ps)cg&+Qo6tK)233YS2qAmeBt~F2&b2~&$II_5+|EoW-AXxZgpt{rcGw5R+HLU@>c1dfq zJlLTmGe>gbsNXm-m6ZhwL#={4u)IpjF6-^ z8aJ9s5}nLl%f0<9h)n1YUz9H|_f*)X=0@&I$KAL7S@$YZi!>x0K3cRU4}T=@=sE{? zV}KIU-CYCCFH`a0fH`pUYh~Cj=&B~w_)!?sbpMslh4gqJ9uXz1&VXL7C2aXPxw@L5m8W+)!x|_Fjp` zYSe+_wnkaIJ{*{hPulZcVBL!2C<9xYJSsw5=8bQz?tr)VkzY%$k=3dP0AaIb)``|P zH95ZR+k>j>&fJozN+q0W_+r$yF801cKfEL-Ro5!u>N}FCd4#R%qHHX#1EdiCPRT=NG0X3=|&kP zBag-+7T;X3{aVd))Y&7yt7--quL?cC)sy)P@usk@cN6yGqs^3W-0G=F9`>lVD_XIl zmNF9(s}0DS&*@9F^09(-uYN;N6cd6|6D3}a-=kl%hP#OBQpgJ|4=3jzw2>VPtjU3@ zkdE1Q-7$MYjWo0w278%xoU*UsEnAkLYPL)!;F+wPwnnq zgKhqn%&^?h|NiYP|NcMSLyQ}ob8}^=p52JfE;5no2mf9CdB zaWc%~V(aEIm)YC94>-kKVd=X;O{EJ=L=S9pWI>!bN+wAXd75UZ%n~u45BvqJJnX|H zoZvU=@R26|nIVp&gQMY;2Gh$ZyMuV;JUk{C4heE4$gI_B{m$$!b2wNn4BFy&kgmhhh6o& zk=^L?+hY;+X084qXvodc@0(Hi)YKX;Ep`F|y8>A$_Sc#1M!MjJZG+ST5J z{k;ZR92(h%(ngnU+XXorw#m<4pwF8VTB&ba_<+@8?Q))}%GFL3wQm-EViu3*dmHV!o28_j5|WQD9cP znt+r$0$;eyX1@*f2nhdWk{I^RE_)hai*favhf@{ZmD8ZDLO)up{9~Al{gZA=cMHR2 z0ht1CKd-O8aHPFuwvo|+nBL(Ry#>W1U?`Hq`dodiH8_X)#9Wivp2b8uv`M+7DTX~D zebF@`5sGc8tgWJ7#Gchg&9sO;wsohZpL@LymxR4)8~b_2W2C|6LWyZd@Up6k!wuiA z2W@v`@SXqaZ~rK4sNFh0Id375S#BT$q$(>q8cZF33%yEqJ8I+@>V?$d4L?-Vpb31(ul|)} z(3mHLZhSb73-72U-rzs`-Zl&Tdo{Wfd@HJA-X={Fq`a6`TwdTeY;NY_=kY%64$g(I zZkX|VuwBoWrzNiJH)!s-2O>lAWzLIEld^ zVj;bdPho}C&Z$Uh^RKI-^lt@2KY{TF4ZM!*mc%vAa%+GYf+R(+`UkoJ26U(5|V37K~gb@H*aCI7^v`Z1>wpzHa1Or!dPA)1qF z(wC8ve+=n2`|M9g_A5JB2}=DW#zN>ohAnKzkN(4Vd*}AV>`bFqLKL;@vjXz$gzQys zdDbp{MKyK;2rJwC`mZMICvwM&7E`YKt~IQ%oQKQf7@y0x&X!nEO^R*&*1?ULTYRM^ z3_djve$gw1PEk@g=$l^EnuF@e+-kpNwcmQ=VB}uG&80b=QvC0KQcZN{&N2PKa0{Fl z!AxoA;6r0X>EQ)2>vbhj(Nu%_f^fO^i^o*NQ3|gQ?#|&)he>PG4BI++F3FxDzzVsHn~CHA{og-rCoZWnq$-WY^NjV_hQ;f#Gjh?oX37xF2_CJ zTM>3)3gq1Q%DnqS>Y2xy)nA$ZVT9=O5zGGDRPa(Eo~X4PX-WB1h}%An#YS}J9d{op)J3Q;G(EMeq!_Y(02KX-+M_fUF1Q>d5!h0s8v@@C%lB;TdDzPxV5#$ zGW>B5`g3arp~Ohq+AF~g325kIU}mESqcEDwRo#6r5F3}z8Rv6Tcyh94icWLS)L097 z6r=dCN-GZ+SU0sh?8`Oa&bj$hrXoJJry$E(lx)b7?A_$z>H4wObTGvR#jyK18%=m3 zLpfM?j<(w+%C~<3iqVUT(rSeAGcr-Nk@X1_vsMH7c??EYIeNQwlO&tnvs3axHS)~E z&-;e(6+$hv-1;YD;kC~;#^@AW_2wV`=X9uo- zm^o;zJ7u5d>Tz*@b{HbRdymU~>4t43H`ferajMZk4x>-Je=8&s z^bSKNmn_qLF!aaEceotbg_nD6SUV zOW5M?dA#0OutfIaVas6Y_x5i<%8B2HioCSCl{Z7NbMd?kMUDo<8I@A<_)YjCT=42_YtS#9 zae3;7%+$PL=Z5wkFIt{Ll{Xw%e({ci`4_GD3OQS+(FcO^ZMQtHk7$6L`_a%(qm~8G zjTR%1jGi!zvg<;$7njAtA`#!@vU-}k{MVdoxyKY9>>8P-C2uv~n%}YG&B|4@??okl z@fvSAebY33e(?1v0MZfB1Bp$Y7xtJn6$FThUw7!iFEHU>>DOB$R`IUB!cRT;`D5kv z(bcOaO=brr`Wq+r8Fs#`#9TUE!7bbQmY|zv-w%*(Qukaq6EZ^h1`d4dK)*pWazuGd zsL_e%J8IxA3>$>LK}X9~)lFr^VlXYm6B6B$Zj{8>Lt=Tj;Bo+E z1a9BK)K%@!=pU$Ecg*@xCsFK{A94CGzi4*R7f2-b~{I_14; zK2qFLFv|&OY)W}es@y)BxiNgewAK5jsDZ-|$GS+w1A!yUg)$PN-wv1jxbii1AZ-Y8 zlGX5vHn4^H=mcLQj-lSv92PGl@h4CMPsy35~Cy`>Iqmo4ZC-= zJe_^Wd*WMoU%E&8jT_m2mIq&UtdptZy&Tv=zEmqZW2Tgp=C!9)h7_mKWbCwO)oESV zRDMzAPIYT1L%Kd@9=YdFW=u(JKD_Ns7ki;e6seU9?&MWmZjbKHBOEE)tS$SvEzi%G zo`2@0uI{tHC-s;mGd&c~J`l#rck7i*YJp|TVi;{c&NNY103Q2t=V(N$>J$z>eI%sv zru5ca*Q+#?Z^SApJ0gwZL4I+**t9biL!c!o!D7qkp~WCFW}lR`_^a2yP+LTKPv_-w zouk43a@rm$gq}+`aJYr{(;^@2&gk6~e~C}udzZCXcf7vDx8$aIF2nzpb#mM%mkBrC z_w6D;%52Nkyz|_Zv2&P?G}G?zt>`~S>^D2_1CBSX))uImFDzNzP#T1aBd7I|u!rx;?KF14s;>-C+A8y3Bpe2X=q@QucbLw87 zSO)9rAebae+ouMK$GLymY#GFw5JbK$IUmp~on~ve%D&jgR+@UjA;8jx{-TLnw4StN zJ|mf*{oZm)s1V#XW3qTzE3%g&EH7u2ozvg(n~S+_xM94&#$1RxkVAQqI8Hh;zU=t% zge!ZxcAGp~5`ar&-t&D|^r81}@5|l23sKDXLGpxX?`Jod~^v-q& z=8wTz(hJ=49iQ`wpGD-E0xs_+x?4&V*>7b3Tv;_jz% zd|fBFt(HS54%Jo>zgDY*>q#6c42sS<5IK$Kk~B`icE%NcJ$LHi6G8^gXx0OPSF;ac zR5GJXT8@^U3)x7fb2R-eC^7{irY^U-J>+i_fmbH`R`Q7+qFRX)tX-{sx28Sh30Rnr zMex!EMBd`Kyb_+^OupBDi0}Q3vFDmNFyrrGGTyDt2hn+l%xsmHmoPYVniYz@da=d& z-W#IPav#g^lO;2joTcBH=$lV_DIsDZ$t+*BSetBz6?rbXtJ9VW)-py(L(t!@YJ~GY zH4uTL-4v6~^vwLp6)d6iS94*~#nx_MH_V~P3eTx{b{=>fry+X`B#zYp4obmc0 z`_sN@Sm3kthTU@#a>Tsc)g!~#1k7;gF=g*%-EVF}Kjmxk9K*jjufW8@_k#WB;K##M z%_IKR3oc)Xa)e7g{)}}L88LD@OC#}X&DN}`J_MADuM24W(1^@!VgE&VG&J$pEL*Yc zN8RFf4Ga8Fy4s=TcNHr2JUAEt=4wf}ZI@yImZ`6&v@=<(`2 zO%it$I2@7qy=8JMrKlU>B62CJFg1Df&or?jh&);6&Jp$libQ8bS+q|woYmwA?KL(3 z3S)w&RO(J_ox6il^{KlF_k3@mY2VL3!Hlq7v+EVlpm6(GdP>xYsOwmQjk>&g$W!OvOrn#=Jjho*n!M{#yACLS}G4|-4IP0ggKdyoc~su@b;q(e~xQouNvLV$1(vFYU+At$k0=iQp&a`4b$>a+8fV!Oo=k z7<0{kZ89-6pnvs>T@O0F^_L!ln}+Z3V$3GGUW~tR_rl<=hZ!%vncN=pOj2tSwN=O$ zRd1`sCgkDr_n3fKDo1;R&Lu?J&L!Gf*%51OglCq21h}2>UKmZcy?lXUzWwzLdz~zF zgsv6rT-0jmHP_i}a&aCM+w6#Y{)WbN&J*^yPtsV%|McVsrgNe9Yo}~)7#Xo#46p>N zRt;;(+L8mw@+L}%k;Oz~XcSgNDD}1$swXl-I&AL^yOzGRK!1yWuhJ=htAFO?d;Xnk z$|FDi`BC@YskF#BX7JTl@Ez3sTXw%gN~UCPnM8S-P0d7f@G|$|z_|HF?>JS~Xt}tI z=j+Q#N+{5ZKDf5wo$o`9(ev%T6Ym`xoHuOA?;|#W0|Hb_|1K&2m_J}X|x7K2Ru_IUr zHxW6u%Cx3;^&~UucQ^ecGbO3EutW?YWl&#l3X0q#*lYUXYM+GF0nX$;>%TIYF_a5N zAP}q7HH#4~a&%nh(h5zDg7x>GfIF8)Z*D2D`KI`{)i&Ohl)oJXQJ%9IyplNPuTQqH z50`zB9vYc~f5w99R7zzzZuP?svZR*kif8?LWdzb(=oT^ObU!Loh=6a{t7Fqjk>81@Gc!z*XH)t70E69DLTpc#( zsBl=Og*Y-%xE^s>QtW)byTUZm{Sa-e$$T35JRMcn?Z{yKtUVo&`6}UZhRLv~E9%Ri zSV`ncRIs`8k3^;HKGM|Gi=X${h19`mPb;Pf_0;HX=xX`*6|fURWLtIu{3%;*+GO&|{9goQdd>$}QjUTJH?3 zX7Do!oi96ux32^#Uzw{a$S_^L#ZR}c5I%sY6EXwp*Ejyv^If-b84~qDQ!z71vV)ql zywyo2hEW#3Pcps%zBX8!UIC2v$X!h)Wtsx)&5|v3%{#xx{cKhjD%4ZobhMGn4)$3k zwsU*s##6O30z<o z88v;)8^*!i*)&?F2KOVZgDPqU`UOLcK{hR93Ep1C;KWNf1l0{brLlJ(gd}cS+Sqm) zXM8|m+oP`+a&@wMB7<&LgnfWW(gj9#F=N8EjGyXJO-xZe+H(<9{;^Gbsp(@>iq-i? zty-IvjDpnTo;GvQ10@L?MG?aK&^wPh3SSF-JO^wOr0GWf>1lO&ZJ5!zG~WEu*8#0D zbM$n5!M|xH+{k=;`um-4n#;*m$Io?2s`IZK>TZ608+u!y8q5Cl6-b->T^5}^H;vqb8;#Ve@^JgA zoKSdnz0c_CZ!=Lz?W$CuI()eD)WFp%z%jSRd8`7;7g-fr-|ZOHx~&B&YdFSn;f*K# z1i=Q7`@%;dI*}Mc4svyLB~a4fI5R9?F~DDGakiNdr(ws88H)btH5IOq9)fE8+hGx! z_piDpUCl(ZrkC}n6SG;4egmHTN`=u-aWMZScY&YkH;0t>aDn?Y+IeO0e?|Oj|W1~~D&z@RCWxfnZ-7T!i3_JQZ<`!zxXL0h$rVJ9_5w4(R z-Dp!Heb9f;TbIk&cIO-a4p9VzcE zm+MCpNT($7JnfuCPZxZSIe)a@pkZtDlq*AiqpXzm$Ib5^@ZO`DK0bz`5?S9m*S5F8Ybx3}TB9n=TgL=Kr_&frYvQM_#GgF7y%PRiRQyKTJhjmuG|PlU!r`!;?4q^P(@ zLFYaYk&EG$_t9QNkUF`#Ex{jkZ`t5zvXLg+E;do2P`fIZD?($$p2Y@W=pH*?J#%Jb z=@LiH#NNpYT~#w;5V$q?!~CX&sKl_fD8Kc0hAvd1oBq%w-0e#817Cbr*xjd1ns1M+ z-wi}$>5bmrzy0;jH0QPy00!Llr~L0XyuGu~(pqR&YfPzbQ;StoG?@4H?EOUJKcI+V zcwp@wFs|#@m)%ZW)!EQJS0)KsH`$pr#tHeca%4GncsdK_l)cPmm8TO(6HIPTX+K~`09juK0(4Nc2 zfuti`Cs+Sx3JpaG5dZ*;Z>*h^_0~cqr02;0tp&KtaDMYnty_6_K<31M$pR&v;nH7@ zO?e*EhlTi)Q{ajGwAIbz>Y@C#&=TXxQgf2cy2XoFj3&kf{gCnQl%MIo>Aru~~trJY|u;s5S)!$FE%l~yK&{fw1AWHf&< zQEg#=PYY~wzD&}e*b_=Wup<-0j7zvIjL>9oC?a`?grYy2tD5Ljzo%auGb8GTWt_-q zd)3d&qxD5)FGPH_KJ5xFhVAzrKLZdZh(z1X!}Xsap%chj(+Ni>K^`g6$X%t+8V z6t^iRUDeZ_)2iZ6)CM(32JZ#mJ3W-sJA^%1hbLXVQzc*qnr8Gcd#xgNJr*b1XV%vG zm~7AgHr2wlH+P`p!GKEu`@8x;Hm!L9DL1`sV|NiGhFwt8`zPD_m`4=eC~+$)Y5W+N_Psm=XC zQst)>(8>#nLEY3_t*83WKkDKH&n`w3Cg^KT8;WFLhu~*|fU>(>G#95&5Y|(KT;6KB z>;O(Aoxv+RrrLCa(3*#LfQFBrChatC$?F#NKI=I>U3$t4Zb{j1B8+g^H}<1?l25}4 z1oZ^rDg?!H>#3f?3OCy!0$%2aDH3`+3C-ys@Oa)*t@(nQrAb#jmmyqTTVKdc13^$B zcu6#GhzJ8!Y;xCoh&b1uMzjd6_aKonv9@#}-iMMyVnni4oE`b6MDBBUSiwBPIa@7* z8R{?>mXxQX#?Ov^a-bf;b-=5xwuj-%I zKqq3_4hNuDCx3U%XEdXGcGTXgwnBu|1Q6=^j;tMnCft-f2w`r8Pi%a~^3xb7-h$#E zAOfF7NfmO1h&<03{Q~B?pye5d4sfM?d6wqQnS6%K&TSkXY16MJutU(4@y&z;4ob+Q zxe=AP>n8@QJKOGl$1kvBtY36GsRInPat9qHqHbLbeU5b)J=A4RXw?0^&4Vm%HZDMf z+YwTPFIcpInSg#AxYf_5pq>Bvi8Wz|jHhbJ3CB6oyj3>A5Xt2ekW7)ls4xO&wVv=y zI0RM?ntR~l(fvX+hrI}QS5qf<$Jw9s0~!63>hNtUftotGV?>KF?7-%&r8srnKF+vF zlxwV%*MMmHrNzwizZBCp)VWTXOtdW$)jnToO1icSiWEv+41C9qOGe9HX8k3wyr{jr z8d`D*X-N?MBGcYtDvp)Zzvr?Wos>DS>ILcM5K+mzb=*A_^VOjq=C!>MLAAPoS3mLb>z7S$oVB0+Jzot}`On~^Ws z3ZDdA7eoqFH@G59pJ(P@-f;kHigq&u^lcQAorF@PN1VrCqJ`&p-QIUl(1-BNY6Q5 zdbe;tFU_pf?mNNz@)qj;cLH;Kpm-|PxFV9Bz?@`bA)4c&gLuhO$P}GO!hItPy|BdS z%+U3#b9R||tFL7-^au<5&e~c)-$}|dUXZuzl$l^B;0L9`kk%DcuAp-qUQ1n^EXgttUx6HFf(2*e}yjHY*NIOl= zlm*|YU12z(Rkl^TT))A`maG`k?W1ZG zG5GO3+$B*&@kros3VVI#voZfRQ_XmfKxvuZks5=((u$SkP@V}CS)x1ZYl6x;e*>GA z0GJ^R5S%@xDW7!5GoG`xrRo#zMunJexhGyCpbqnN8PQp`C0EfH2?V~m1F_cbTi>1W z(64Gz1>FyxerfIU9;(RwYqO(J@NpHm37&2wMO<)29DuJ}*PqWco7zG4f`|wv6I-Gb z0nRdikeE>MQAV%Cg8ul$BR=I=Ie0AK#+-NZ*isUet6j!|U^}^9d@9xdTtO~CP zR~a9@I|<%bOq7Mq12lB__=d{tWCY~XYBNX}m5QS2zhgz&1E3Sxp2Hjy8qvI$v;c3r zgmm)!u_cYq$%gh0YAlEmFq9C1(N1I+XN-KBrZ6U`tSi}O%v^oE2>*II1Mi5`)awvD zHQ@dxiHw5&olnmpCNHD%sB_=FRFZbfcsiM@S*zRE+ic^az$7~#Rc60gtO&wQUnH;` z9u@cV*|7ha<24hlJvUlKHtPphbjcb%WG~N^BG|R2Ab2eDE!Yn%inV~u1MtH7U&SL< za_>R<#qqgt*Gc3*j3bnNE{Qi&IkUtv=HX4!R}m2d4`APp7HpVxokAag)1O8J0|R@- zwBS_SoS@7fBK%KZy^ZYQqpNLKOyK+d03%OK6DMH(%+AKI7A@Vo+_w3MSWkg0L72pR zs``=$*7^ySFhE}t!L$`*DDsH*vZ3L$5X4I6G4}kY2i^!?Uxbk$-&-8Lvr{6Pddi6N z>0Sv=KuA=PeMh5@#^N)!pcNr8mKbwS;iY)$y3w#Jq#|hD?y#6b$n#?rOyqT|hA!(8 zfh_mfI7*BrGLrHYwL1=wMNzpBv?I6{xOI*(($sfNl!P)ManrqwB@WTAG}EuL7h+oL z3v6ISC4x~4XP0Uo#^&P)f{ojF{tyn$T-ARNAuS7{g2%&L*6D9EPcUI13eIp^SD)L^ z|JibN(&6P?6mVUK6v2mWlP$nab8lqRBE0YoT_6HHGSZ&A^@wH6jeg6mS`c-$z36xpeM>R8wQ znq)P%lWt<>J&zR?&Eo3oLa(}rFjGX^>hhz$l_kHtuGY%$W~B1{%q`Lr^}{EW&y zJMF_Sdb_&Le7;pYkOtXrxEZM}p;%S(BJ%RDeMG*2-(*9yLpm=A+!<MfFJ6=B{M<~pzaW!agESYP_z_Rb2-JVm0?G3q^Oc;!1l0VXLRoJQ|FaB zwF~iKZLyFHBeyDmXV@z0E8WVAZy`OL@tS!D=qGBgRqcS!Uo}e9= z(Z%k}Q}U;gUGc9OmxcOhP^wO%!A0$t zSe!tdSAOj};XY%Z|1A+=#|$GkCbdE|EC5`(2xYX34M8#P%?*OaaIHn0qC_tk#-a<) zZ!pk7L5h3U;Hb}ww0kTwA%{r1JML+@{#a-#YLcj{SG>FjeW($EE5_$Hg-c*7i zS*(7lt(+15+2maRR1$AZv-PNS z&P3Wz^W%!z(OPA*ruLc@*V_ChTzib%8UY#SN*;b4G5*sImAGzt?U#9|>y z(SH%?Db5u4&ikv9(sE!xqz>wR!_cWIe>V7Ppk;7pd?Rwn83Ut5U;WdXF)20q`TCl9`a}Jr}Qz={C=P}}njcy`9_u4O@ zM1nhPq#KUffdNZ6MBb=1>>ii;1!?yVCtc!7a}`qd2?dYQit!5o7rVgQVRdAXDk@bg zQnLyoz)ggp26;Fckm{&Y=UBqtl^AkOeNC3~VdE2nZcGjzhCiLx^&>?X(uz<23 z1|P-ZJuBDrnS|!#d>iM=8G4K{pM7M9+`$JuM+-lnG+&d@*s-hmFwUR|AKB)A9>eq4 zxO!LO+SCtpk>dKb$z5Z6jUDxOHM6?}**2e~7p5=2wRqo332TiZKNA?pRKW%XH%2~r zxW%nf1KVD5bq{k#45qCJ0?~_Wf@lD3i-nG*{l)5t^_>=;Qp|Yl{7ZHe#?}(@DH6@! z$As}aV=7ye05)Q(HIPsUD7EA_wm|MQyM{rXdE`Mx1I zLPA^fcqQ@hRk&Nccz6>(B0_hIAY{ZcCdbi2(UO{XeYMxnyxMjGn*SM*CaZ*74vh5q zbsDO4(X}~dYCY#+*D=vDQfHH)&x=u``tSDP{67R~XDHBS_2tEghax3^KWk|+GcZ_q zP`5uzls8h_j$I+IWp3Q&&$^an2(T&-RR`xyoNaN=b@Q8^w}1^B zirQrqT`_9TmeceOSUHa4E=9a)5_qj{$#gKrbN|N(iP_sH)o{O-%LJRODayNR*F^(T z*cpA5c>C7)S!T=J18?z2m*m(WY=GCoqZR(zzVbv}-IZ~oSkjCChV=oswo`u$?H8P==`?Enh2yq zXF_6>Ay79W^72l7L{vdFm2Bi-TGZp=D#w7(5)H&zxDi#z6z^+7Djl>RM90I zX8!aR%T!#CK_=70?ACq{8HLeF`4FzIqpzv-<%qUJroHH{6tO(YZU3#mekzSuT0c2 ztvrn6q2(BNslac9C3qXBo2K+*d|+A2mBClK_1|o_l$Y-)1qM`uwWyQFpe(ioE8SR7o>rnke@A$y7H!Y$28)-p6rF;CkOw zs{AM#i|K#TW8TTV-#_CZUg6(~&{j-BXqQQRXvl%V)|@4JodJC#d!REh|0(2k+|Y-) znDd&>{~8D~nUH(^N2*)2Y$?zy##_|dq2{OF?yU^zUXmSzu_&+r?)-ndvT5g%4FtD{ zwFCeYR6$&RyJsx7E_$KzXZ9gU>|I6E;?yTd~?cL|O&*E;YL- zDsF!HlEPo~mA9yssef9oM3mw=uF;A%YANJV3T>1F<%$*qvdF#l;qo7S8Du?WJX--+ zqTnRPNT_~?G?s2iEl=RMUTy11yx;l@M+yKzf!UvJT*9%i`*C)Tkp+no5}tdomT-1N zOuyQ|%|Dam+f)e9T*ml+6JvLb)ac=0{TgAtq`xj)hywTEM@WUs67ivx&a9Td}>&?F< z$ty`qj?|MD>ATPkN$z+Rb3x$5uB)Xm2Pp0Vc^^MMcJ{Hl+~!ds`(Q1*ZGaHF?Fhtq zKb|GHDg`=-E9$?AqsSEMN$%_?N-d|X#n5_>K1=GHKddMBAzs*DXndS(vMQEj- zGOip1YhMK->xl^iGQPF(b?yok#;pz1);!ckxP@F3+5;Ey+1pKP*?|N%@FxCT{MxZO zk1l@v!~{~$Czr$;8IxMq(3n6qWU0$=E^nYuACa~f2^9774a_puT53q|OvMM!Gab%J zF+I?nh&Ky9ANrgmOt9iEwl(vHZk8+g*DRAAYMo2PEBfM)_k73;6Bdosk4i(sa-!2` zIQEu&CGC2fXSHvJDKDw2-mEP#_ZbUcfQrb($miigQmK?9-Yv>Ol?$@uz3q9elDOft z3eqNRQ+L+ZM*+(w_m5p4Z={sybv&L$t2-K3oZuBL#}IcxeD?VZ7k2Hte~FnneiD-j zQ1~XP@Zm;-Q~ejhyy5hNR;_tNk7CcTnEnx=>6tyKNE>C|r%2~^tl{*ljZ!7$z=ufT zg_f!IpOhd|-_a+`ZfZQF{sNE9=X`&`|5*3K?y9n4lLH>u0AT+MY%punzZBR8z~|iifZU)vdJj$t|{rNWd@vC9`SDz zOUoALzNjfpbEE+u96M>7YkXW;q@Lx=$;eC6slg`O<=(%?YDeTi5HD2yTr~AkOhilTte^2&=aHS7J)Qte{jeKJmXqi#;UyY z-~!8YJPh-xy$-d<$VP>Imh)>Q9KmHjEAGN(>)NHdw@-Kjd~I^ zhd%e|{Y$UWlE~|h>}2u?{{C=HL#6yBJU5@NcbTV2|B3}BH~IvaE3aIr21*A>9f?= zq7Qe({pR5M1^!+9!b=`{5Bb1oVf0ncLx)CP^Es}i;%lj*nGYITK8C zg{Ai*TN9LCFVV*mH$*q@s!OhgpxkXb#X&-{Jq&tlIVR$dgd4wKMY*;QOXW_RZ_IJN zKKvECOUcVM7U&1HokXA<2Koy>BTcBaFo4CEh7cO0?0|&&>C?dwF^34x20y5rlOp#J z@Wz8&ay>|ue%j5HxJh=X8aGm0KUpa2Vr`jZcg(}L%J*6Lre&G*vct+j4n5|Yjf73rcGL-!!14DkLms4z@lKo{secHm=QoNVAhPcK z5$y<#Ehk`Bh3&Yx-;mMt^Q#B7@}AB_M4XA=?)i+VBJ^%}1?&%NYuY&!2Tbyl&uz7J zC9V?iWcMn&e(vG_bNZhKwzbGTwY$VfB2GiUeQotF`Ru8?w`KoAF*MUD@T>6A?UrH6 zRZ>=ocg4n)!W%oZ8p)+nahE6pGN^vIO6O6&BdGb~BBR)nqB~$AS+AGy%vjn!j{D#% z_i6%uu%JR8OgTs9=kUO8i{uTUgYjYP5r(vz*W;kn{?W`~G3Yp{)%PfQ67*S1U{o6( z)mnA^ejNT$Cy2O7bY)+XF#$wAo*L$B1R?+%-26`=w4@g(nU3sw%?aK9r__Bcf)_9T zYqJTp9w#2(Sld-=0e0QbwofnW|F~$+)<9|0b3z)t>5+iT(|2V zu$Ra4`Fx!2_s9JqLHXCH1AslU=lI&oi1oUK(i&@eWLebd6f%A-=0NJTKdbuxs5#)@ zE2H~Eh!q;nbF3QacKj8hXAZn*NMCQw7M!<;OSV*Kj1;jTkCTKMaR}p*{M?VXO&C`i zS@V7agxNRAckV=ownoy{b5?#S;dB1)u^)2ro}9b$#3nDdy*73S-%h_vK2mGPIL2pS zm2^aA>%uNqtSZ!LC@pF@HTs5pv%<>0&^vee8k$>8;)04_dvRUCOVSJP9h>z-+o5SD z1hSp>o}GheS5ApN)DXN~{WALjVn8A*Mqx=0Cpz64W;*#BvhaL7qkgOj*}DlJU`=VK zR@4RaYcJE^2-t@uvaHmL@U`!WSGkla`4PQOz!^~hGn?xy+i>|975{5MK!fzFF1n2?$cXONHU4ojwfTKn_m#f|gjuswY=JP|QH zflZD))&E@%JYvUtl{M?Rz}qnM+N*fHJ<%)QUU`|P#&fj;PHSEX}!^{Y? zq|klWjc^)Kh?va74$Q)kdmNKH7QfkSdpWPWPSuAVd^huLtE*d`fv`FshZ7DTKFoW5 zX{Ot+qwM3<1CFyyzu(4!zqhsEnW*A6)16%Y*edU(-*{&GtKx9N zQO58U&sOZHT%#eEfZ8&vYNAoT8$IP_u6DFMjA=)fXl9+SH@2N<9QQ1yP~_CGE4f?R zGahVHbCSHJMPu>KD7!KjmJ-DsABYZtEDkXXXVuMMbB*FMkT{eFV=JAh*ObXW0O<7uLyrw!szEmqzB82q%{| zO?i8#cc|mH3&pPR?=7vdZ%UTPj6z(pdXm1`UWKKqLp=QU zr;ij^f%fpN8?O0xb6SHRR$ldRq<-#iKy&I-)1ALt&ZfwU%g=M?7LFw;QJxe7P#Nj_ zEybR+{A*;ksc)V~Z@i>fjpGT(`w!<$+}QmN&q{Ql<2lZWoH#4W=BHCAdynshaWIIf z+5+ox&8#Y>k0ztoz9A~HKAUqs?lPAfr=Cd~ZgUu{{@%Lq@X?aqs4_wH zpiS-Tk#| zL%(QheGlmJZI`7Z_(L!IMh}rH3HaM#M_KPuPMzd!RBEAgv*IAdQ4_xlbN+uB)6LIe z@|{zD&qL;v9{4vkt*$CIDTqgXb*u>23*?M_kxBTCXZ)*1#e&jzW9y;8f2z-7>Vk&=lr>~0 z{MfMg2TM7KrmiLID!+M+rS|{czpzqSUyry$#kbnDuXhozau2F)oLgy2Ir3`D5>A+o zoe>w1I)t{egTAuIf~Gzk)_H_WJGUJVp?Ngjw>U57C_u%VJCWNzsdbEf<*KpQyVF|h zLN`qqCeNbciue=Pd$xga1y3$|h0I(2aC9ASNz#&xZzS>K}5;;bBA#*qQcLh%QF7jGv!cE78!vda;pmMYru z=0T+J3t%w9zz;R$iO?d`JLm4XyAqmB)FfN=h^iKmGL zL_5C4ur#QwvnC;KHqmUshzvld#JY*m3go9aq9)87Wgl8Pw2hjkw?KbpOw%QSWZdp= zNmdv&fn#PPhNg1Ypv|aSrkq^sqp7mWb@mJUnK%uQ>XNPtsIcl}p3gMeC<8rsh>>a& z_f9E2H02=+1prB%*6qM|0Q5A2-icjS&m9lBfs5Kkc+N=jR4?;ttMK*GCT`N-+vWPY z#jW6r>K^HvM&N+YfgGbMw#Okvko-E(0nZ?P}T9_HASp{@$gZVnfwk9<+G!KYOa4M8C|NB0pny=P&6MIlPw-tei}+^_|g* z44p#7>c;%Rr?m0-lfpO7`NS+2W5#=4!}*qalE$bEu-$r$rd=BiVo)QrRyFvi_s|;YU3p6+FT~LLb#y3>jBg-ku?Di7uCI8f)#%E1 zuGn`pjw3PBlWA;4g?c6aP~J`xn&!1a|KxF)(=x&N7x<0DrnT^&=uwRmywVeIDVuga zA|XXiu8pX5FTScYe+!A}$&C;fox0Ska~{P{+nj^gD>oU&WFkPNW7>HZiKwOJP6b*# z0tG}ye(8Q|`SDClrq1Rl%&}0-HMp<=`o_?fH;&DR)=#!VKm4CPZ+_O5cVf`(&$r82 z#-#m-q2O&GRY&Jfk@5=zH9>_Z7mI{pV=tSo^16Oh%Nz}=Sl_v@)57q)&QROYXnV(h z@1px$>8g$cbdLgMQ54=Q&fC9@s8)Q{j&*g=X|rtz=C~) z3;$+kY5kw_BLUr z;0Is+39MPK*6K9&g$G@-IRzN@Y3$359~Z-3AZ}b8Vfh95KUxu|?lUCw83XEUk7+F_ zPWAbR-~PeRt6+(VDo6KcD}XsamrRW^W)tvD&0aH2t*!8mJf1zu|AOFT>lITCrq`G6 zPx-g8N!|}YRm1wBCdKtIh}kJatPB(WIlQR(5qDK%n3q*oBi_|Uj?kONuaXX(IALmk zv+}*)vq$6Do11s$3N&YO4NrF;Q3yGDkP&ce{En0q)f5w|TaA_95f5{;Vrs2f=|L$E zq89vTuDdk(Ri5ysER`)bzpQ&cr87&PTJNI$9LpgKkfA_hhJAmxL4S1G(7F$p`%|$4 zzzGPTK&mOzGw~@sTdT9o23T5A+mwB8lv{^3aqc>U_^)RlI6=baIT00*mMc18p`vTf z;wJw63NP60XPK&ca|)g(V|5oL{*?ILl~P1MaLw&(eO^_irte%BNN)O>y4)u7AOTu; zyu<-{^2(ALwc%8Qno-F}EV72ZR0qfM$`)JPh#hnbvT>Hq%3pI_rg#mZ=qyX;#Tx*lH;U++FD_K0+Py=r5m{A-kKI)%9cIg=y_e{z2kd|DWw9-qJ3tySw40$U9$%~pka{B z{E3t!OIzFrFdthxzD5X4Y+e|gjbXcsDzXv3Ifph)t_x|*x-R@`U(l2MFB_=d`939? z3MU`RA170g`PqGHYDzwx1XW=LgO*}Lz+4_0-_c?i9#pd^L zuRMle0wH>Zrz)-}8jqdddvYI~r;(>CNdb_G(CKSG|C*COo4=jcKF^^+`NV;MR8gyh zC`|FPB(e_mvec^!t1+99nFS}9ZEevBA{46_B!y8>W!+tHBWyMOiIHCUWy*lZ90*Nm zqHk`>e>~5`)gf5ukME(B3oRqu1O?OLS={@rU_qf1{El#Z71~lM;J;Ul6LoTR?+x%y&izrdv5zauuHhsEG8$r}D>Zf8;rwmS{odkzcR+BK z>^<*RA2|ZRDK2Ma@@_JJcqh-!;A^W0Wwp`~fw7s1BIJf@iT%Fju!MPBg*adzl`@y( zExY9etSIw(Z%#@;WsJY|?^W@h@cJ)v_iC%z0ZMG!U~GbsE+xr13H21Cl9E(f#HDC0 z8jk0WkvYJ8Rpnr9KDmwF!m?hz!Qfa%j;Qd3P{O*5{j=HxeBc&zZ za{HRpPr~jP9gzvKvHU#3p3!W45c2u!+C`(`K4zi{0ifWy2v-fKkIvnkV~5IsJQrII z92-;u#xF8rVo|1;S8YduJ{zy-8qGf|iR?EwD*e8y;*y)&NpRq3zvV3XY%)2VsXHrZyGE{^=-sBl)~E8v>=c8Qi>#e7=1NwxGWA{HM;2OloUG|nNj-|)?o zB7E`BQ6~5`bKg9S9o#Kut_fv!N|#$Z*tkP-#_dg=|9{MI(Gj{ED=v`xfmbs>2Y06; z_pf1btM1F4TQQG|8eTG^Ql^r#N@?PXdhUYRYE=FSA^_%!E2xZ>z;Tin@icXo(kTqr z3G;YYV-J7371JOLapA0G=(=j~kI{fDb7wDvyoR4E`MO1K`D;p(dgwK~?u8R@g1|fs z!!X%$_m5%7iMe@5ltgU)6#e$8@Hq2(pLvZ@#lLrE1zz&LmOjS``&=YYfwl7{^J_I; z^h5<;UaGT*@TcsPmDT(u^P^a>`}#EMwPJ#wbVp}Xkz<&bRJFlha!q06H7;+49E9qA z8IG4c%y@#%PDvsK+)p&ni!@fHeyu5)<0rAakNrh)QRi;(CPeD(l~+NkHTpeR|JzbC zkPd>}4qW=nA+9pe)*s2KEax6s?JRLtzr4JX^>si~C3`X;w%A}+7=!yoTYILLO*Dz$ zKAow@p6}I1o1c;Aww$aFm?x}*s;Q$;+Y|^j!QZ3(>EXkeinY$FIeN4P=V!^fK&nVbsr|IMsS`6wLrzH&DIgL zPT`&%TccgNRsY{BS`UqMYRV00GWCr#%=e=o2|uYo+&CXeXmND>WjcGY1CwiL8u;re zX0X}tr&?ADxo(Y=QW07#lhUfvG?GsD{!u+28TF-v1aZM}`dx_Q12MBL>eEGY8EYG7RaXn#MUVxAR+%{lV-5Zr76(A)LhjM6p7b_%6O8gTWmJd(t$ zUk8CFOue}E1W`HPr!|0<8}w|{grKJHLS6Oh4RpxGAa&u6keZg1CW8QXqh{%Wl$pIT z(}vL3RwPR@-9g-9l@omUR48B`oj)rIkA7szcvet!qHd$E&Q90(5Cei-&?B^(d109b z8e*;P>y(_CJE@OkL6u(Zht#wJ?05VG8@_SwP{$JeDxPy@Ec?~l**-$<$X)B(ueJDG6%xqba^s``h9 zTad-0fm35{e-4>@5^Ed3Px_5u96=esPSA2^?mQ{gQ!-x0AF|bZva`5zbc%^mx!=zr zsh6G}isNJ}Ime-O#^TnP+^ovlDBMC3>2bcO#m%F>=5)A9n|hR~?MqL)bLVc!y%Ovm z>IK;9OJzyN@I1l_4!9K1Dd)E@?3~y;e7VKpM`LAQ;t1tOaK*h$k=Id?cb7y@eamJV zGogUdkOf?$+^K^Ms(2T;u2R*ObB0`o0cb;UDsz41ZCUfpg5RIugq%6!)I|QeKUksD zax%eev>J~0Rh^vh+KBgYm62M|7qq5o2%cmkj!1yr+#SRa%h$TYG=t^F(60dM2s(P# z$OP6p_MB=X{Wr(hSB3l#PUtMG)fsCx4NR*$&BBH>)MUfb*WH6y@hxGyfd()GS=p!E zx3^emC`hX2^~Wi1>#=*CT*K}yQ@zVu>#>BAEcmFtSI_F6$s~(!!+r1{_IKwaKO^o$ zdqfh#hBk$kQ)A?ac79B;$wA+%cG{|oyQ(G24;F-cMkd?qR|c$_GBhtV8aDI@!Y(%n z>r@xD+Yra08sAl`iZO{89{snjO*rN>sJsQ01I#j+-b=co@aEVmKXRy1 zKW9^UMg8pGlL%(3h7SebdTbyj2{`ABV*br3_elGysAvgld=M;chOZAh#PI&%m@gYz z>GSK_*qU*}mpX-el8Z3wkPs3HU=p}lR>FXPC$lCK9(q|?JPa;dGhv2Bt;k0a)Xdn7 z0gde6r^WrtH*elNA3oo50TO=5L?NpaFVRg24^y}7iNYLq;p^Nw{{@H;emMVp%xfVQ zUqwTFnT-^8afq3b1bA_7WTl%|>jI53KlTIKSoS#*5^lSfkL#lV5CSA3c}F-wH^7Gu zn_s`jiRf%*n4&+mHy&lyqFuyKr?g+>$HwbtH{{vs@|`IA#j#^5`UK0a?pK1!3rFc} z1P6Za2wc1v#8&hDy zAZHVU-Yr~lZK5I6XBL?5F%ug^o=5N8=^xSIW>P6%juwPO8BKeOTwhN#4DMtnd=L0F z`nx$}GB%iPO}_>w{2To|@I|8ngZ?5nFg}{?i|HKPWoN->aLF)cGI zeoN>2&2yC~*N406J3HYo5w2;k{vP04LVbX^=PQ?%<7nPB_?SI?=Ihy4g!+^Fk1uX4 zxJ{f<{uJj(Q~YxH{%e0#t)R6%4bO*772D=a7q%RME+ae97ttkNVMH_hEB=FKr(O1afl;E~`@K(*`N zY$+ReW3~+EeH6rqcEx&1IVEK>v4J8~{TdxpE8SRITZ(9yZxLR``xF-DYGd~5_*MV_J8EP9eY+)_3Erh-BVB!j53>)%Ur>?Fhpe#V_)7{Uj z$%9Efh7AFsP_1x+WAu$eYHr!-wVkSqI;X0Rm@l-kz$CYo8~mS#-ZDmCmK(pQS#CTl zh@`=7n?8gD1~SOx*fDP07~CqUcgVTB_97*Ln;VoZ50RK|VVs32RPteyZrTD}3YM_Y{rz@=t{k&ozXB2X&$zF9UZ#Nu{ zkf+D0=;^VO#_hvq?b_eQCs78ZKLc{%}NnL$P6`J3W8 z=W!5{L(>lPQ_&YK=y&mN-pJjc)faEYJ{CG{;_rX0rf!kQ67(9;&#ipQT;-JUbzZ|| zNcc|Cwf<=1bVF@??@~uWaWw(JQS4KuIz}(i`X#dGrC!Vcdv|8Rh8Vv7x9VTtj;{j;0>JiIcB5R zP$d4j(OYcl&pHKLI`n=XUpcCRPJ7KO++Hz}gjn?uPa+SP`lg~wxdhdKnW{5hxt#>@ z^5emOCTYo@z=^Klx)1@b;^>74q3R8IiN~qaC--AjeYI)7h6x+X8(S~L{^fHNMeb%t2;~;yloXW7yzVNF5iDr!RxOs8?F>?LIs{UT!<>hPdVAvMFJC z%$0&ouUsU6_dAHWjx%>t*2&X#{gT#}&oTS6bJsN0gWT{sQ~wPknCPT>0nw-<45CiG zeU@x`-D9)iGLDrXKtzjP?QO%WGkF^dDs2eZ;OelD8hf5lIjrw9dE$i+@x>7&3f8g^ ztPq!)j*Attk6;n0>r|37C_JcB*!dA>JtKy5)NGrLuu#k|6JMS#t+|?v38N)*?E|6A zVa%)O(=DO|CsmUcc8yr-mRHl%1Au*6SMc+u2w(C~f+L6)#`*KmBOyWC4W;V=0`JSg z+a!)I-OD`BL_QpMpA;7;@MVQKnAEXTwsYIHR>DHx=$esSRFremsRB>`xLYf zQF2^lWL3_l56qJ{pI>-=!q^7aR6~9WTo}g+`1yiAHmAZgkK*$8Vc)Q}^U`m+*QH9w z>D~E|Uu(d8>wg^VNBeM);@6+M_Efvju2SwVA;BTw7sV>}0}H@+`oWLJBX}TVGt@U( zcUCm}aXGI-oEdI?p1^mJG6?`aH#nv@RhWVyK=#+NBPF31FbyhB3+ds6mW5%(d>escl+T?5GQ~VQCPJCpR)sI~_5B9) zX$NFa`%)(3uqKA-o2szji{iP1Zd9C+nyWM!z=bM&w%FoaXsPoc07~blM>k|jx$H8P zZ2Cl}O~FLQlheTMYdpDdPm0HvPod^Xq5h%oY_}J?M6YI2Q$x#Ct2~HImL1Na8 zr+xRzHtiPqJH|J)>S+G)Tk3cHA&dHblE6J1k^kcYh-6a6P&25ujtuI_ z^`U>@D$SxBRrK(_k_Wkm5E&ajLG~YjS&c)GL$jd5pl!6_rlQDWwg0AVXqFnD*XX0} z9k-ij9`t?678i9Lekzv;EGN5U4IS0~il+Htx_@sJ!P43cdM9}>SQe1d-SL%qApBDl zVd2t%C)X}lUVM*j$4`NzMrrY{ZMGW1J^Ye8>-JZMx4)nNZMqca_6e*w$q)wTn%qtO z+2kMkLP>RTVfIzwJ9FAqUE_es-I!rzoMnj=OT&Jyf`>g1!R!q6T2Bli-ewekATMu) z4KX*&XWROh%*;l9-Vp0at}(DN_rVwBCMw7p3}Y~UptBy@2?_XTPI>QY)2{^XjUW9A z!Kn7jL-Mk*|9n+l)Nd;=GwBu;FIMuNiF}G>U@VuEI1355IJM+t|YB+As zeJNNDJAsPaA|sbzJ_NZN{Hup?woy_42JbJG;{@{8z{U*!JT5q^ELbEqSs=bYcs*nJ zbgRQ`f{pqOE!8T~W{?tiJ%feE@q_obn8*JX9?BX=IadH@K1cY_-iJRI!KhNUl6d`!hGcC2^ve9)-vbTvI)g2OvsjCw- zSQDQUb=;4QqEHRapgwn3P$8Dw)fl6`J|T~kA?+Tyv7W5ez_?^c2E_T`X1gvbES6!x z#vF~lj645|KT++*DNy`zp-MBt1h=R8k*xRHB)S@z?c!G0)Y>P&C7U$#l}k)ICspa; z^lCMyKE6*ojd(gR!A+3mlwE|nO7nB#FEe+Mb=IeF(BlXAvoh%kHlIg!I{&8k-`M;x z;tL6%eP~zOUrLGk_rvawGt$>3HWGJ*cgiN1G8hj5ue~aOYmT~{({_>|ZK_7tE8rU4 zFv-lTV^Lnk5J&g{Hu)i}aOZdUqmh zbc)~qp8NA+7H9H)s#Cy&hCc7g&AxqORXe@`)JtLauY}!gk6t=mQU0mx zw|h-`MA1_Q5&=6Dg%%kduo%E6f6yXUK335fNB^i@osY!H;S}yQqeIua(@m(URt;Wi z76=oAApmCT)fvoXbWw!Y+~LZ`j!64vKe# zZ|&Le{lb^$Fb%(3{2H{?slnWyO^|E?^T{W5LSc$fHTCm^%U+9Dl34sxq>W6ju_&v2 zKX)0SCdq#IsC4o33;)c*8Drt<{V+s%B=Jdh5ffcEJ^MiCv>tyx$9&;ge8jSNK;iT= zI>f&d5lP`SuKq|4q4t>dAa=q@^=pS_ExXem$&X8pJts_h?5uGD_b#-XL`st!2DjkiUVDU|faaQWr zq#DCbBMFR|#t3mtZ3mg=kJ;kYNU<&nz%2eQqc@iL9<%FNf~8x}=aW_9TlnY~{&5eF zv=;ws0$CI8Nt5qG#@aea)0#!c)~;n8VJ9eb5bCO>tC4LfjD*(*)*B*B-022DwrufT zF7bP!X>I;t<~{EUi`qz0wZ~`9PxTpClay4pV`*&uN>XTO&LDhKZ8p~Scm*)a;e1j7 z^L_u1{l&DYryroZCpz*hn)jFv%P^^7O|TV{yZ8+mJ@FmZ`93f1HJZO6Xq~9%gs02? zj{dFZtJ@5^$5VsiaI8yy{|rK{9$){g+y5@P9V-iDm0^0S3i7jR>^G$>y!8!lx+@142!+1J+(wf8!<~K7~F zw0L7D6N#kB^{XCB4h`}vhw$S>6&boib7cJd2(z+Bda>C9v!jgpqeDD^4Cj@>mz9O0 z>_b}7%lrBrF@l^|8?l7R^8;QkJkm&%V#BQP8TIz_d1lDGaC+r)DQ8Tubk7{zmLoH~Yq;DSr20Pjk=>Si z@pmx^xkjcNps?O>QFYP(wy(v>H@4@o@LNGEPp_DqwM=;#HQG48sx-3MS{r=;Z)V4T zm~9fEnz4XAa`^D)|N4X>b6;OxmFlQ*{P?Tdlw)?Q$Q)qKKF3wA)_JS!Y9BwMPNvv@ zYsl<3WYSWRZ;>yy$~dSUT$}ISlcupBOc_UpF=1v4){vinQJ)i=i=RqJZY5x`zIes% z%!=E~W5%kzOfUdl@WAP76e@Tg!brS{wk1=$xs+|dVBgOAK5l}#)qDavYxR?DS9XPr z+J53vhq7umx1p10K>%j|LIjRf%$Fhhm^v$Owan=aeLm?;te6f{p zA?(R+YR@m(_@_4Hvw&8h{F_qpy%I<^0LP?tX?y#P-qg)YFI7DmMK6QfJXiZd^>&gk zUW&ykkdEb#WFJHl)6hPje)f;lqAfK%(zCYpu#4gU;_DRAm9LT4vQ3IS?SHCx;Ex|Z z>^DCy7l0P(2NqW=K7`qyt?RkIq&2G)UG5|G5lEKcnGCsE$tU)Kx zftjF5a%Xzw4sBYl%rPrH?B|AJkrB~;@p`cFu}fRVc(rn%_m?%a3~W$KVf2Aqva`6U z{_0>96vOW~QF*uZGS(+G-CiH`o@F`{=Si0#4FII)5KW+E|IB&VufNsFfc#QFD zCCB(>QHJYrdMgKn6mk!BiRfigxw_#KA~52FP={E=k9eJ#$Kq+f^jj;qCJfb>?e{hB zz;a8a&qwy7T_$TrA9j+DFB()i$fA#`<*wBPWuyQrcSdMSkWKK0H|0{^52BPwyEJgU zzP|r|=8FqWTNSqN=&uAC9s%|FyIe`GnhQ8r(D}p3gmHuYaR0*aQ<3!A)6-RLeA#k- zl;*Ei)9kSMFB@WX#XaLR#rcE*l!rtGr%?9GZp1GW>rMxv-zZsf{q(nWEBh|RcqRAT zRs96i)rWo5@H;L+CInSwt*smR-SnDml?~TXxE}TJ!j1ojfZW=&t%^QZp6+PD?4oq`aWccmg#H6ns?0N|@GSgJT)`JXnc&L@4c~ zC>XS5<i6j!K77i32KCZ^E4}-`%dqgm<*rxk z>8&%xa~#c^?$WVt4-lFQ6&WqKuUST#_{~+7A|9m+RU|?(PX9Q}{2u~k78>-9MEey> zKq@vSqk~5p46jUA!U@Wg-U(=x%m!N$VKZ^9SKW>->we(%`MztuYU+VHUzy-I&4Mi!Jpp#ckDpUJ34gy)`Z!6x9d^ZVpKD!(a55?N+uW0T%{}741Vp zRsH=i!9bdUeUR;z2ZPasM?Y=3(AQ8W`p?}`x0{9;6wko6p3V8bRoNVtDaTI0PNI7^ z>|yab(aPHmH%8mdo+BNjb7EVH^*j9;xAsdE_X4y_nX$f~qI(J>$h!Mjbt&045%A)X z8L@-Bhf;>HDmLh*da7_c?X?DAeW9LsG&8M;-&9l+_SpJRrGao&rPf4^>1VwqQEt|w z+y&r`JW+9^GmOVLt8v5IKq?t=l3QB4)|1k`e0PqDvy``?p9~j4M(*cCvLN{n!1LEw zcTCL9<$*@SF*MO$-h=Za4PpT1cVQ-{*m~x1+oa_;S>&1amA0kBeD?7=++AR z2pW)?g0^03Q$1N)So_Wb-j@31SPoR8ClGD=ps(eSoBp2e_5;UqV@LmU>uhXr4Za5n zA3W{s@_j>qs)gC&By)1araOohi|AmWqAj5XdeeiovDB&ul1e`seK}x5+mAY`Wxg%< zh!}JB8h)`39f|E71}L2B15(20l9vYRf{@tGU3uh9HcA zMW+AAwGVhmm6(40_SQn6mJMNV%2|)FCoF@5;FCQ&ALzn6IlQls=itWcpu)05(w&pV z{IP_#izt>A_iB8@=WI#7B2lE9ny^a3i29ZTCpSos)-)dc^^KtoBoFZbAgQF64A9W- zV>%y4m1oR%wpqIxkF`V*cJT~f$RsPpzA|6LViXD`S77oy(JB{adCkGojki)l!id9+ zrQ-$yh<3P@0sR)KdfuISPD0T_ChuF`c)6L>L_L4aP0Tl{`LhfssB{L7X9Vf3dGypu zr@xA#9uVT(vyH{93-1Sk!S0U-leh=TS3X@-x#jin5lbj+-P+o~O7;sPzJlraxIVs~ zc#jjz87-RJ!~lW3>3)M-yTR-Aw&s^!h#B3p%{xFLCI0ln*c20=*_3Nk7a7o2#T4d5 z%OB&B(A_{=uZMx~Ee_q9F4Q=MN6Rp2gCrp0)vc%gui4;rqAPW59OgsHbFsid;#icP z(|8Z&U2aTWf5UfVsN7^CpCbc77f&|-igOj4s}3#(mh*wqRZ5%^=^;R;ezC~lj)hY> zhWC7v5lh$$Lb%p_9U1CtFs&%iCN!8XWV6r;)&$6y;3*${pO$-nmYdDu^7;HfjeP^! zT5EM?^<4HLH8!6wnHGbD@+wcBvE=+#^WAyu+t*Xk!fNd}@ob*3Bzk}aIHqd;5N&a( z;^z1v^mmXTID+sTqvF}#)*HZ3hY%$#M89L`cwja&6@7gM)*{8K=bjz)Jv2a`rpAO9 z>opm#64V@!^Z3qdH=F)G|Yc)Cqzy( ztS#RE8X1*sqqoG}X5y9gr?FvP82N-1$cm#SzqQ=R;~!=ysa7p(X~&w2hsswve+P-t zOvSu(mGmg1cRpDTwgiijXrqKU#BiJL$*RYS#q?CT)Q;xykw*K zj|emFi1GX2u}>Dp*B3S`clXfg^!V}Je93fT=(4r9%V}m6HXWYy%+&YO_|jhQm|(34 zb-GwVVC_#NoNzn2dl&g1neIA81(kh8%nuE}Qnej=x@twO!w)wasxd zZppl5$W(l8ZO%GX{g+5U-3aYtXI^$T*TEYV6%jmB#&PAl9jyn|sT)6sH?kg2LfKYi zB#qNT;qHX1p}h76HlOHiYb>i>YoipCJmO687?Qq5bgNyAXCS@E#1j8d&|2)1&t&t> z#@N*!(0dTEFw)j#e44!d`7Q2i9A3V78v@QV^Y@&hzNpE zL^A%$x6^M@VkTaYbQH>Gb>BbWr%I}w<=jinO>942SXa?|BNtg`KX#L8O#302o|+QR zZ2>d!lv9hV%L#D8-}__bKs|0WY7i*R zB_tL2<}&sPFZ0lqK?tAUn5~h4rE&t|>mw`&ORTqU)hoi<<(4L~&9Y+XM{07T(NZS$ zW=^;UkA^20H0rL|IW|QweT{chW^J;PKc-F+rUgth<|dn3e$F27>u3gd_O#XH7Ww$H z+U9=>+O+mswu+h)V0gUl!e>2o^zW?xY@fC0m{`PVTXPmgo@rp2O9n)753+j8x&Ofl zc5Y(NkxwfDD=s!n#uD;mlKW253|lYpfLji`NJmxoREP8SECyv!?q=<-PG;K{QlALk zA;aUtHKPF=12;BiX?eO+aktA`HaAuq?FC@H&8T)5WUThPrXR6}!_gpzBJCHB3^wsP zXx(+PL~mu-O|lk^dD{wY$RD3Rrx1~bROG3}dLOKSCiek+z@p(gZ*%YDU5%?uR5H@1 zSh`-OYP+mln~D#Ndx=Yy70(P|y=uWRzeew5yG8U@PBJXZ?f6&K9{~H;6?}b)BC+1u zz!tux=&jxq#|sh;Uoj{oNss@rEZR-myu796HdR4NCH?VMEQX@20@Jb&(M`|@aHBCX z)ag99!bjf^GZX!@#8cS_eQ%-VtUL1n%bd^Iy+lnib6OyFo=DmIag@HD14*52Qdr5W z)6H`=_LY5_t@%9xZ&-Xw6P$;Cb3(HFW5L6;SWml0T#Dbsh*MYjUhac708?U;Zr*=4 z^s>?DVbyXI8shGbkO=`sRG!_^Vntc#yva0h-bU#u!}dc0#%*!RQGYC}KZfC~3EMsv z@9!VypYH3f8)n>}G0J6=^qCE*rARPu{P*Y3gE@z`Ux5=2iIJyqsqJLT$O5v*Wwj?j z@3RN0#NhPR;a?{9w=<6z`#wanjTJBX^pq@l;*Z8wc<;as3I0p5v7P@M-qoQ5Vm~tW zopxoQg>Maoys(u(k@DJzSJPIT%OU7}Q7>PQdT*Q2YK!W~5nnpbpnl=mCvF4>nLu1s zUB-gTI*^dTc#MS}*T*Z~h`BAM>x&gN{zmSeQA`=Du9O$f7aqPsVN6_gL;^jE7D%eL;hJ8%;$N_i%lbja7fN^moAw2$! zUZGeB>7abrVLiL81u6Zia8>sn?0&L6vS{Px9hY;2Vy0jNf$E#21F}ZGrbBt-GpD~1 zb)jk(p~ckDWv`MeU@Odo!FMI7&p!6Rsa@+wFwbc%b^9??=OAQDdc~NA6+t}mmYrY) zS)@+E`_}-@u2u(vra4>Us<|kjpm@p5LZ&fe^!k{!VpDQv?yrPnbkXRYFQW6(fp4SK zqARRk`o7zm56l5YZ^7P62gfX;x|n;w!(BU zxGL)|3W0Rle=;&JV%yWed&5J)eZo8-%AUw5%Rde(Bo>5M}6 zL|2cInBTMEHkp{Rhz;egl8Wa;qvSJG7o%pmyGFi}UF4>NGcm~X=7Yhn0H7^pV@7Y2wb7f^RO8A)Je9<>v`|J;?wO0-?X2V%aOnuyi27(WvJCCM%&Z%$++Sm5tl zVy3o|I$PBWdYY-r;6Ye*#ca(YYs6*Tv zKNr{b$sxJbPs~0#Q!I}|g$<9adkg`bzOEybIV~T%2Ac|Q$Sz(OpozJS@p%>7csV7^Ng_JUuox ztezjE_w4~NY%B`FyhCl1Xlv{Nv{+#DJ`6Xvgf;Qc+Je`gd1qJ9wPq3o`(NZQ)Vo)M zM=GkJ%oG1e^E!nAXV^BUn!&CqtR2BC4}I&wF8_8m_(=Jlpa&7{d50qIdW~d{=j=f_6?^0te)myAqGv~ z)BC*_vL;dvnA6y9$?2pm*Qgz^c%yau2sp+-tOlf!b!l~7EI9M}QyELw4TO8_*4R~l zeK{s+Do6>J{P^zWFggT~GFP}*MOKou4y`od_}u6K$}HopoSG+EP%cnvTk;m$|7_RA z7SvaO`ec0B*&El`6g^```U3sz`MJ$uQ%1iU7XhGT!wKLjOsE@ZPM^b%EtpLp2^WT| zE%PQd4XSS!P78)jeRJlvLEXs!Y(IdfCiCNU<45uA!+}{bd~Nc4ZSq>DCtDR+vJWFD z3A8x6u-o@)!flJ6J5giV5lZ~okz>Z<0`VdG5Z(OB+~@7FjDc0W!l>HX?p`rXCoo;( z0^SvH(~6Iq&uqJ3wmEu^lmf(aW@YQ9Y1C0y_)pnB*GYh}ufa)WJU3mApAgMsLeatv z?!YQPY|_;CAGlgxmh?^PSfM?s(Dq+3oV-t`|AGu!`HCz7=!kubk4Fl4`sDy3`)@Has_Wi3Q~4O2fWtd;o`Q zmS2(XsT(8cry;D&haSF~+>~|D@Ql~kQ5eh6TvxD5FRnQF^BCqGI8Q}E4tYVa#3f$& zI5W__AlxEB=f^P(5gW%Q>8OwvB?4Y`VR~%HWoim!MKB%f;hC02ocAtt*=4@yD$E_Q zZsTz`gR}(jkjnOH{&SuCYE`%A38sJlvara;hB7cg!qWwc=V!%Q*x60NjGF%UiZJ}` zHic|IwUNDrlCj>kYG&XSO@^J5dm2o`dpJQMKp@L~h5}Bh{KQWErE;ex|`a~B~X^|>X+^<1=+6uiJv3tC*j*Kl7QsL$JU(f zAY#wovCJY#%zX5y#X2L(xevcKE4}qA47&UaX{RkoEy>HKbQvr4J1p;raRaWqzO7Mr zx9*XKfKWibGS4d>xOlp+QCrP>+QJwlO1u2j!5MVf|D27wJzDrN-)vV`ga2DSqA8CR zdTFcIfBblOyi+^YxGgKkNKRxOLGZ2Zz(PiUX53fS8JNeHFld{*qz&vA;3)!C7%egbS`y z`Ha<;j=6DA;=c1#g1&r~;&6gk3w9aar(&2jMZYPeZ1_W}0OTia$%;+;6o{9vJ}fPm z<1Ibm8JG+{2#M1GyWaZrL5qd_Y3i#ePIE5Y7e|XX-ss|ubhstE&TM1Ow&VBvhFzeL z;}ThJ#tk>g-DCenDApXRmvI<0OiIAZ#;FWs?*47Gj6WLi>jRH&^E?79Qv+#$YFsf^Z5XK~W_xxVEIZzWY{4>S>Yim)a^5J;H)LjG4tr=?&-fkU z+`%CJ;);c}xcv1i+O6r!@ezUQ{pGXNACHT+=;ANUNXi$}l98fr8$!>lLx-coJjc@7 zev7n$X6^re_2Y|0La&+l1lj0#nc%Q0hRqBd{lc9z!K_ui-S#g>&ii1{))F4LtjY4zsX0bDRsM!ErH&9`JNYHMV^mG&1r6K4zHrw$bH1y&f| zTNW2JdN2z}9F(?x-r^(Gj{S1E< zGt{s)8wqTW4}VrASGN9-L}k{NS~NcO9%JIa!?5cr-Q6XASqrQSzfrE_WY|s88&@(B z2`Wc^(sdl$4gR%Mrjyo z<%`eydsF}}%cQOyOS1Z)!)bLEE{$;6xw&9C3ya*#E0Lo|qUttBQ`mB!#eWR`4Zv-$ zWOh`(0H=tZa?1!2pD`tKB!Y!?nh*D0JI(Y%Gr)TJ>)1O&7&hDDS#tO$ryi89?H=ct z4{_<#_HBFn*TUL9dB#F@F#a0x@_P1+USvet_p$Z@uOo2X(fu;PBNtct^RQ|0eflsJoa0^j@E{HrsB~{%{xr zPi3@pOH{h^99RJmXOunSkHM9F)UAP6s6}+S!HY*%u%2(i|NXy5vHtRB#?!I?Su7>j zEIIx$eN(g=I(z@wM~D%tP1|)X#Hd&i>@-=l2C`x(Re*MkyMVC);SQDg{Fc@g9P*D7 zsD`5{?PwDJQ}J{*>#mJ3m)6i1&Tec{^o2GsLU_3+dje4-AsYu^h=jaI27zrktJd3T z!jFI}Bbv%k6K}cdhmL&4>)g|XPHJx3nYUiwd0&^7a9mw%7yFimQ&^6-F07CApBlR9 z<%#pm=Lp~8EY36dBBFdf>$p2pH`Gz8YhLD;iT*6%gNQo@8R0WJP7loone^fO+i&8h zE%CHOLtk8FUivN6fy!HAV3Ld!KmP`rw_|r*0Hevr`J(V+Jn3QkFiJ!G< zs}c{))$!?P1TRL%A{e~#Vpn@`^DG4iO{FvX0s`uM~0R%(HTr|ah5f6s0r@u-)`yO9 z*2>O@?~`R9$66S4q>SRi1&^I{=czs%n1Yo);^QmlG?Npn1_EjCWSQ!`>;7`j)T-<9 zf_WDgW#j@@cQJV|#Q`{Zo>NV+X}m`iTiyWbelEJLhvFMF`+|7NVwvCHHkEx3e{hDe znje4G5>!@cw;?1^dBSEOS|w`Y!}7u(h0aEC)teMunpyi-ff|2HGA7l@5A8~h9qpla za(sko*EYH4waNi?R=&90D~|_=%cp=VtHP}tp_W3uC%orVU|zOGKgUFBng}KD$XPDl>@l_GX(>E1aW2MBCeYhaX zV=4R93zqm9gj!KgVtqK8qo%cE>w-8e8q^T3RFki4s4t)e!{2B(vF5c3vni-G|0|~q z%4e3|KwGfx-P0r~g(gwB(szbG?Y)TKh;yRf4S~Srlf540&FpQ3JZ7snIMe}?tw|2;$0JMWmVzCosb=S4C>Ku*Z65VXS^k_>HadegPK z2l1bRikRTdZ!$k}k4iX+? zF;MC*&ZIy;+Fjh$=hj5Gux4yzz%X}R3?T37nw`@x=l#`LJ0`916L!)IO+^#&a+wpzCal@Uts_%C8@Bz=YOT&1qN zVX6HBf)4jMDoI9`tDWR*#`KoX!-H4B5ZPHpn@)656Tg~=g>MrTv zdVD@bF+}hsAFowq)tdTNZSrb#$ayIr4idJ|o%s7^qw=m5q$;`aejZTo^MTd`undsr znQD-~ADE$f7;I3_MDWMM&5xly8l+f*55s-GUN7Tt;8>k1)t5suJ!vn`&*-ZKb4J>LrIv6_!fXhV|e zpBg^eX3Z*7U*lyyM?HMzWMY*^Xh_$boq=YEjy)9y9|y4vTqE8m z5LohOZ+sal#awf<%$#}z)H@Y3TD1&@*Xzs-g-!N{Q9|I_EojHLxSkIdjwDikF>PiH z6S27G*wnHjEB*Nw^pXn|`Lus-_gY`!f%Eiq3l@SzvC~2f0-(R>LM+F(DQl$VEIdH- z9AeSS{f|gTRRR92fnN2E8Z-M)DPOQo`H6~=_PY|LpSRsUK9%m;o^`q4#Telj=)L|T zLOPqNX7%h#IA@PAk{AMUsQgJJE{Crfe3?+EES>V*7&jZSibYn@w&0ktwUO=BaR7C| zGyWiL0?$>0m*$aTW})u7c6NtD_$MQD!wot09&u)6Wr0fZ?67+NHoXMk<1wb?>iF== z-3l@!<7Zb#;sUa0hJ@MS9!rdj3K%DpK3u)>KRD`LKyqvGm>~!vR+xliZH)`Tiy<;V z`w9Zqpc?yFa(!WF`Oo;;9?^4GTuS0dA%d_=+8=%nRfWS1$2(gB_g$D*gBiznrfF6K zMnmnTu8#F5B8cswPGH&Ho?S;l=P&wAbVYo+*2_FZNSJg4do%fmM*bXY;dwsrfuH={ zl8oj)dmnGI^G4H438xv^L^scdA1B7&)u>l!VohJtUXTTp1ua5W6KZC~1%+j+zl;f5 z2LB5R?qyToBkc$tBuQrrpXq@JvEpH?HMiH)tL!rW!|LBcT|sekGma?^C|zvO%H|g4 zvtN|vO30>Om2~HOotd@T*Z%LkpNuHYdcaECFzLe__vE1NS5WWN{M|u=!HD804lN74 z+*YeGtK!|+Cqf=|*8Da#ews_m>ijh4z9;k>F)1%*k+che7la?UxRAI(9BG+#6yb@U zX%00Kp#}<;c5@3{Lu$`3=I_nzHHX6}sivB!IgZfIW;&hR5fG268^<0_H0e1|klswb znLoKodMp_a-QjAcY?sThN+Q;{j}H8302-snQYVDw(HYpzd9b*@{R%d}ImnflL;Qb8 zUtQy~+x|?x*Hxtl%;`|h96EZ;x;7qWT;|EGtT|S63pXJx+WE6ex{P~&Mr{(D#7h;O z7jGp794*5^%~cG*h1{J>Iv3=ALmh#7CezM=HBww`=DB&KH!P0e-hr=-X!4iayL<#V zxqAK6`tbj=?D$N&VgtL<$iCq2iTNRR7sml>YGZ+B9oX!b(^+k`XNR7I8+ZMFVE7u~ z6IY%@*p1jouk(4IBx<8}eCHsin_TQLvKi16I3J!s;Iz}0zebs6W2En(1~Sq?dV}*f z$6~#W__2~8*>vC(t)eHgYoCfz4WX1g_KRliEBG&#Cx>I;NoQmR)y5zAGHv!dw1Cd& ze(S!?%3%xGDO_{>#3J%zJ(1~~%wE9@H2a%yz7 zBEDfFbW*>b{#*CP%JCIo^dGVh*ozp8pjtQZ)BLSP*`5;X*7mxVVx6wrjl`$U<*Z4L z>J>Q=Thj=#F3@rM#ZNtJ)oGTuQ(p#{4tzPLz0W5A^s)#Gj({=$f`j%otv|^IO;@y? z9w1C{83)vwDEq_#3}Wkyn(z*ofCz}-!dt&MVbD(f6AsKCw&X+8U{Yq$U$;vVz$nfS z1{B#U(g<4AX|t}Z6vIM}Yx6DnzQR*I&Vj=0zj{zcT80VrrsZ(c|7?geA z&&tqwh2DX3Z~xsdS2;b}}tFITKszE=K1)|x{s75Q`ZTC+ieqYfqo zLLTX!#s)1nGoD$0gu_ib8AzTiNf8-{EhqcYqh~9YWL8iMW6pYuhTNR>AFmKfbL%{zhjUv=9p_)`T5vi1cItF(_%=b z9`(asUD&DW&y(JL|c^v(#E7btha4+Py zj_0j}Mdf3=A$s_qjy>642XGyAu*X}MiTslxu+0wsK{q|o;<+tX* z$sgxX7eG5x2-pA89U@eQnwu|E2T4K9Mnh~)vP0vbd-fa;Xw2tEb3YgD3~Xxh8yfs=QA0;L-vR)qsel6Wjgv6H|>b7`sQSu9^QVA$>$aEgmJ#3g;n zp?Q0|;~21Pa2Gg>M94i48CipAk|?6YG6(5tt%)zTvm&wJnKf@=Qo37E`75UP8~zm+ zj@MwD#EZDTgZJ2uf9oeTKT37rko;>ON&yw)=l8@^6h#TO0lR;ob?*R}J%#s`qLJ*FEMEl?%!nCn@NRaOL}PKBQMT=_gYo zRvywcl=y+^3(3mnqq_UjFPUs#IKoijIoaddxf#U+g&EOez(KBjsFZRUwc~x2%3`bx zRKf*w?x5atHta^T=gFM!TT_{}xL@l&vQld63m9VRRw)lScP}+g~2CJo^0(|>5=l|Z8&jJ#DhVkr^ z5&#C0$z7>ou69(^K{Mr|#@bzL;#Vxs#J;7@lbt_#{cmcM@PLPS0k~h6 z|9zt$`gzH+%-i4krCw=GKUXc^g-_G=yK%2)k^3R7=|fj1PZ-Yw?jO>Tu)HrNzpPgV zL@+6w6Nnh!Wehk#E$A#3pFx_&U!)0s+=YCWjy@|cK1@+)Z}!c-X!<6>BhVn6B&f0wi=BtASopvsxpW%wmfy*tQycZK- z`s>1idB0{jRlDYKj46-O%(+**gQKTq{lFLGaqL>LWq+#pO0(m!uQUBRQzU%(x<-{Z zYW?^ulgdWHN^Nz%IKf)LfoEB+hV;ncT}*v>3O|jsOtS#4z$RET`$iv-4wKU^X4zCk zIkubb8Jy+;ms-Et9t>)Xl7vI9loy4PR>!AcSIWj&lKpTx<~;!OY(~*7-voQDpf-?Td+LkX^DkXL;%+)PrIV+}zJ+A*v$06!^xW~FR$}-ESSiL*p z9rc4kzoMJJ^@MvlC}YknF08v@?N;?ZSa{Cig&OxmB1939eX-QPqcTjp;9UwDDW9IjT(!s?w}*7 zc-{K}t>>f&$H;7>eA31u`H4GQg%-7|D!sa~J;b3XiIE{7G9$%I-WaBxPYBr)XJ-O@ z{s}Dr*NvifG&-7m^-5DYVi`ZB-mV@*XT<%1wUJkv;T`3Q4^`maJpn!YFaG=ulk%;5 zE3BBz)S5#|8+kD&TMshQUA|wP4stt7gSTI>`nBHj>8lo{T(3|BVb&Lv`+iRx#R_}V zIJ!92T9grivIpiwyw17NZ!P3(mFTL5(YR|_URdWF!9AT(=A1vaHS=sV+R4# zg_dOMMStu&{&q*~3*s!r%PHM|!pCWhW?zQ5tAT%9IdKyiVSlX(g>}6^~guQVdheu6VI(${}mccloFB^O! z@|W-wG_*ix=IuKhuSB)Le8%i_-}T-z36HM^ma|?ok3xA&22;YG!W|FH9v+S3_SU#M zak=!d^vJ%CLKYv5eNx645z3h<`wU7!9KEmA2t-nJE3+`QY@F zq3+nxmLtOWS)||@e77}%Bz8f6^BxsBf@Jhj?OaxNzkKnSq$3~e``*gyvg@<~zkj6K z`|0-YqH7~EN-CNaizSg(#ejaBAZtyWtDapOPD8o_w?Ic~_v#vnO?$i$hc?SgZq~S} zZtQEPrWB`DIclumnzpo}Y}ctlU>{WmPjR_;1fh9vxOPpoSEC4kNy z^{?jfc30soAi`*s&-|;|nzw}nE*H;C=xw2-XZgqEo**O&IB9I{oY}}NUmVr`7+*m+ zgz|1u`oQoM+kKUly8+}t(1x95qgwV&LqStxe{XTtgsks^dPM7!PMkwaW&YvO(T8Ns z&Aw~>wre3cji+6jw?j@&ruebRsz3=rXDbl4HRCf_Zxm@o7+jawc7i)nhD^R0H9?bg zerPlTUX~|CX#Vh?LC(V9?hrLPuJk|qWkPobh087JRgKcRTo$=OGcU9J&glDn%{QzV zqsk|ezWpU)JABodv?Q<)`DuKHpW&jtNIqMfQv}g2Hz49GL+vTM>W`aK;=fA0AdU)e0oa!ZlnOxJ1d78>$`V{JF`0X2 zvH39~q0?)@U?4;y*=D$YmTq6L^P?hZ3$-0m10IzVbQ?{)@zgbGtakbN%g_93Jc8ctdbf4j#CqWO0Z4%gvMA zSFg&MeKyU%^3hwFU*yvxQ3K%#1CsU!Qied*IiWw{@+|$?wbb3(EMP_e2ah|_~&)W z=@AuenDr@4utf3%IIcc%U2u_$Eq~=Y_iB=@-lXUO!NoEm$2~F8&xaEl%D3}11Se9@ zy{cd0f}ZT!m-ACjN|XfLbxxp8Mw zq`)s*Q=vFa+P8PbVxp&q!XtiQb zNq02}yNpYK3ja=9>GEgbs%zq+4T&J%%BpLIVGka-&hKlVV$~ZSlrIq1Tu6`wSGl(_ zs}}^McME8S6AN*~V>wE|h%ei5 zkR4GOfc`fRY!xJ|hbT;G!-LAreYqDOA1m3DuV^NE-i$-H9;dwqOdEq!2kIwAJ>kGc zhO1$A3?0eGPtDtZ(N1suQ$*JO&aRU+uQxXR^+gscnrGd|KT3~Y2tTZus*t2`xs-Xn z^E(YN17{q|r~?SGbIB_sDCwP*DNj8B9bz4H91T(LFnv~}D4Z}GsAK5mlP zG{HtjJ|o_mjIZ)3Q4pjobd$|*JSF9roG_NpZgPq&?;XS?h*tN#*Pk=MSE!8!Qz=>oZJFQh{hKaZ1)&&X1cJK&!?ByGlQ``ra zJ>oI_$(m0v7OGXr-)`Ka$t>}&EnnnG}{(?04DEqnj{<5lQ&D9H3s$Us^r z-tE_+-Ptx)D#u*77a+t#zL{e@A~PvYhAeIdB?g&!Up@H%hWjI2U-L|y!G`e`wLW$H zzOaWD2kte`g<}zH{Vl{k+4+lP@`nD)EHuCdxE@6o|=eu8= z;=Z0=Tz&gJkSYJ-#=@OHmmlQ)NL%>3)1(U*_PeA@CDjo=8 z-*Zm1J&YB=w29=0OH~T?FVSQL>s`?~ib>Gjsu4UOj~aQsUvod_h3hm?eErwyE*2BW zW?}AULQn{gG&}yGjYY+>(iZ-)dD-776_3-`eR-&hl~st-LY-A2XHbG_$?H1=n^~%$ zb+8g>huXUhcbK*uo!zG7$jlR|!B#$$mj*wZCi~)_>6W+JtW5)R#7MAK-;-;d0^U-} z)y9X|;+?{L3qI6un{|0t`a>rOKikh~Lk}X5D2Ooz&&OQ)sX_M6*h)xf<_1cHhW?pT z@l2^y=sWBLi*$B<4NgP{ORY~dh@rD{04Eo@$gtX_Nd*srbNUY9!~&eY|1BYFHK^mr zE&i2=aNR>aaeW<>T?*PhPgd7a@#{0Icc~EU6!%TV`R1-Qg-sqAv@R$ZIxD|-u$dUM z(Wl7^cG_iGW)$&}5~AO2oLN5uz5V_m1i!_8FOOKE@Rm}p!*E~ue0mCq!K^P8o|o8KD3mxVX13|rj+{V> zyf|?3TX%&s*r~!JXWafdJlUn#Oh- zcX5t`>0?$O>9;m=?QWOn-oPE1wcw)5JQ_^#gQomF3##aDX7>VKABH{0njYT?I)t2X zaTVGz@=r{^N@)=ZNj_|Q;x;XJVJ6C!NnO~?n&7@<^szYk%qh))dh_#p_leVsT)@`M zL&t)N^hC3-#^h|c*9f{qV9Swoiut=C_fq>NI*nA2SJ3h74-n1dN|ZxHL8Cc-o=6SG z2zS`!BV{O!mnDpJ+Lud9Ub9lewqpiuy0iD&|eNQi!l8= z;p4wDATv|yuO*vnYV6k)0vp~$KVz6y)ZXl*!_K?OA*K6BBjnpOK-$30TmH*+E@E6P z!&SYR@{Iz&`%UVYWtqPu#2z9r6M%Je{q#^@CJQ)Pr=ku5+E+me7mw0ku)*tx2m8`? zOs(FE+_pxk{U;eCGLR-51LPjZfq`F5J9@1;OScK{hF%a#Q7#~`9`stm?OL0~uus_L zEOiA4_VCoTzu7JPVvPF7O1l$2_g|O7aJHZT3EKUm;R@rJV;je%GXRSpA2YHg5s<2n zG5@_{`<$`1d@^jgP*XT4F{<+(UlC2k}iOHpep2#oBH6Q zGcQvB7?mNMoXR2NIMECjnQKI;Rm{A3sB-#O5|9uDb7oE_rl=4k12jtM&7F&`kuG|uM zBllaZTs1oAmSa7CB`kD&RCjDq!1tOgBYJM<-tE@A8?|vFhPebh3Xu1^wJ1QV=;$8P;x9`yeivD|Wk;|yns&2Ny)M^N0mCz@HfGmhKHCvR z;Y>~9&y8vi@xu0rrw{CwWxOIBckykL>`!uLoU|2AVh%m(-l(Tv0?s16i5t|gVHmphzueSYf>8^k){Re!fe6NV0 z6n~PO7#L3-HN_Sodoq}%l9r-&rvR8!HjP|L&dtM6Lw zCn719i*`o28nIVvuKft**_pRW$U>B$^}dd#mK(orhv85jEj;9FXTvO)c8eINCDyy` zCG)EfOqJ|I9*XB>sgPLMaeHRn#;x!0d}SWQ3b<~3GdI*!(@WqkO^lEfX6KdfMp5QqPm zA_K#HFUoe5l&I3{QHpKL1#baxzjCO@J<6~2o@jrdHbnL{45n14xl~ZoS2etEmJFz~ z3AdeHFhPZ2G$Sm>MabdcG;-ALGshK&#iA~E*Xa}d$KU#_Zw3}xW^1NK0g!HY#63vC1M^iwxRVtU6Vif z-TE=V+9q`=2C;g&(4_val!PzRkMCerg<*0pG1i!81Dd`S$>aj=Xt>?VF=l3)NAD17 zd5INer_L!QJh;nQe(kWM1F@M4sI_uj@?q{a)J$K6;&mj4p)Fx{cOkup!wT)SN*vI0 zYTJHTVoQ++yYtpv%azskF~e;79LqhZ|mFr3`BaXej#&{zQWDm-RD^oJ4HVIk5VT1iTJcvM_xSCcW;nQA;j( z>3LXal3pxPm&`>k>MK;nGR_%>=G^~ipY2V1WgB|ZUrM>N^wOkliYGlo3(aoq<+7`y zfUAU+BGgQqo=lTgb&=Rt0`rFt^H5I>i!aV28=F$bJHLB2&+0j?fBSdjH>Ec;qh^z( z>ei)2ycWeWk&Qxb>kkQ80FNwkVgGK-t53T-rrhkg2NF3KTpJK;*UvwVDGZM0cz3|K zvC#0xhHo&a4yQXD;xwo@wc%<-`Z@glC2Yk`|K=DG98lsI~e!V%07 zU~lUo%Qky3?Dya{g#lPIHL>q=t9+TmxwuQ5i_5>RsMgp$S_2kwwiDww%V;R|P@^LO zWxNUu%G^JoI`Ro_`JRcJ71PT$e@G+jWUqZ{3Jns)KINA?o})eSTG0ZG0Sy z8?=2xvRYgKIwyZbZ|W)hphGlS{~E|ffr@tM;iA(Qb~MWa7L!vbJ>5J1f~@<;_l~l3 za=Rm@CSG95Yi7eq_RW+y6ZXHXr}>q+Ge~j>u1~Qt+{LiWj;-Zwiwf%pygqJy#hz-X zgEV71X?HEXhQ~#@^on<0%0HI-JLalHGdJnxH(rYP(-pfpq_&>f6HTv3%c<=giRbVq zqtaM<`<3%RJ=rd;T6M!W9@XcMNUdtTVCIxuz2V`w6CScbD9U7r$nTa2Kox*`xo4J| z>s$j_UY*Jk>pu-(o_8^!%d7sQ;H^)2Hmo)68UCx25h>|RvS_KxZ@)i<1PjCdtZjq% za+ZB|%bTeHsr4Keoq}oM*%`fQPTc5OMuGEQYNcMHU zu*jz6dpn<}gKqcG7Vp{om~p#dx?O)F&E$`nU-6R7A2X`lixGTJu%?2hmRP3r+W?U< zdcy2SPwknI+|admFHPHjNUSRxy57nvfB@AdSl~<5smTS}P68p%Do;}Oc}}qGJWgtH z5C#B5VZRP=4{zwd0?M$KjpIM)Jh*IuFL5s8ggT1`kzB* ziJZ>XONj{)4u1@p22S(BzY6E7_eH$rHa8!J-*nA`f=$7rI}te9T=i`>;wzJjI+_nW zW4I)1xvA}$w=wn=Zqiy>VFkm{HK;cf@F|(Y25nsQ*=^@=GVuQZfZ%e~V!2{oM8JC!t^FVuqJ~#zRNNPJ$&KZu(e|Gt1^ThI~DI9dCcERZ5PEN4M z>=M{V#33PZ_X25M-mlm7-Ns<>RJ~w&{XAR-Ei+ph8jVf(^ZTam^C4=9v=KLXqyjn~ z=u=y~?K4huW&U9I0rHM5ie)6ooSft`o+YSDtzFlTO<#7qaqDD)`3$&3iut_NuAWd} z-}h=V$3RN{J#AnTBIn`gJE#38->m&_a3nSAHLSOmrZ&c|u2; zJ?TXC%&iA3z6Ef5tqb=zXs3U^UG3lO&1SS29NTSXgx74dOmNFp+tu1KGMDPT2e+A3 z#eN2#egQ>h+j!k}g3kS9YLXs~Yf$f@2#Vx}VVxP;D3pJM!>L#p%_kmuQ{4ljru?KT z`&3$nE^-Dv!Y(#TUzHU*JI->i$pcq>ukl($2MAeTn0B^lD68^udbdcgMinJ<_bimo zMY`>8Fj3e;ax#cOXl$_z!$d=c&pD;d2e=@-bgLmif%Ol(cWCKXCB%Q2v1*L`dNwNi z&;mzX2XpW%U*@P<+XhZi;j--g=C|UV54JykH@QG6de_NCx*dGic(vHTn2>4Lj(->`n?V{oqW z$_#KStqqOVMSb$Ee0PF9olj}N{PvI&>SV*$C9&5ffxVBjY5eTgrhz%VnND7scReCy zldRxiT8y~rLk%2(8<;RhTNb&7RPpQ>n=1Z;wZ~2E{%HWmS9S#6Tlf2qIO_9*C1ppN z-~9-eA%CO)`sDCMykPmnbcgr$hbTG3=LS zhk5MNzDssJ*^stn%pgZBmhAri`Qbhk`=`9iJt_Fsp4{0*!N$@dq54j15wbmJcC|Ob zx!|HDN|i^FWIpBJN#n}yBdqX9tjj*m{7$gW^vdU*d(jQ1NN-zb$Q154Spx&@&$m4c zR2ugT^H_1SIt)2!Rb9W2a3q3Uu~Nf6`k=*Xc{S0;u%C3&^8&fMj|O-EgnocyvP=4` zgCXt8V@xz*yK07daP{4|h-k;XVa42!pB|Rqcu%~T8?7NGgE;3-NXb@je6>SA@Sr8X#yakIXSpzie$vKhn{A>P`1oB{Rm zOowB?D#QS4xMS2NMfp}#?yO()al)?U3Qa&M@s#pM>7Ug&!W%!(RC21#>0@kIooDf+ zU(T@g=~~LS;e(22y8n%zuFYCi2k(U`(pWYdNj)jWC!L&8c|bUx7T@4_}t{VRjx55ynz1YoL{L? z%X1$sD`n7H{*i<2(N^Th@6*idG(-N3_|)&0zxrLY26d&$*IxFp7nL`Dsd&!_?fEW< z^vd+=UaB30Xt!*d<>o<1Al=%6Kklll-X_*m94g53Za(;ROtwm?6RVP^FiU!}l8S$Q zyynQs>_@Ks5;NN`U3Z%|jy4pQzr$9FjO|c2Uy_lua~B$qh7dXVSL6>G5|#fZ^0S=q zUGcy8jS5)gKd7!qVjFHp+Yq)d8vmUV>1jy%;63=Q`{DcUDubY(D`U*FhY25BYcbPz zRzK%A@J`I%9*Et3R9lVjE7d`0WKmPMWW z)UOkaM3N_@Zb{0;-pKpma&B%+)dS15)0~&3E~``}uCYv(|H{uiZp;KqB*%t47O>Hi&ag~-;r3$h5?d~A z)oEZi9P4|yj0YkVtDVxJK{Y8ZA)g(^>wiGZY%^Q9J?WCC6O46ZLvC&HgiMabYEOrA zJvQZb_gRQcpRwavz1bu3^9bSuit6%Co|H_!e*~Y~pj}U1JEyNKgrL=IZkqajms8;cY7r$2YtaHile`d<1^t*&SqI}=Z zeS>BTsk>J<|L<6g2K=_Ju>8tnYxGn2W;e=5on!2}q}z8rOU2l#spHig*L5c`nzQ}n zd1KZmTnG;LxKd`Gtq==6`i(3B;{(LZzQ|iUp=+=3L zA7@$MiGzNg@)EMOlIy5{SJIUm&aSzkDYfqtICLz|yM8qu4-?o;LaE-8m}IK(PjVsB zXCqvQkp~WI-v3_8s~^Tl2@hF=4e(9%zdu&JUot+yD4Ls&;jCf0C8HtTqh<889u1;} zOgL~V3?14nhg_#y2_$8-a z9Eh&@eOtfo$asVPyl&c+T2eu~i2@`mx?ZE`2fY{7{Af6GmZVAK`B_e^7sX>a&><2Vq^q# zc`h@7SJXk;YB6$l$5-hnIAz^V>Fd9?-^LF+mo(k|VH>Q(Uv)>url0+qo|!w<5lXzY zx4q%OX+1t@-H{$OvmB<_#5E~M!C!)c-`sy@2EWp%;}aJA-#%5G$BoHOS{GMzAxW`& zgSXOB=7Zv<}ChfMXe~z^ua& zvbfyVZrS2y00)SFuYPgonY*KgXv!kjtqLKg=|n0Gmo>M+SNb8g`jW5>mbj`EN zh_oz)87(@LbgRFWoVPuv!+;UA0`}0T?ZytzE>#KTOBr3yx%&HD9BfYk6H%8uCA>ax z$$RZHPTm~5B;qOm$U{eUIY}dFmei8#LIV?60208}sZm z9TPa8!Q^9chK(w-=qX=4Flh3EfR|aXTx=C*9h|4*H2_aGkY#JbhNB`^WBoXlWphrG zc(D-@R@(^7G*4IOM-K;%LGWBfo6n0ecdzK3#G|fsP@I^L8*d@*4PP2KsNhUCdlqu% zZQyR@Q=R&C>0&7*W>j>C|0?D2Zka)ztvVt5Bw3;RaH4GTPP_^HRd>HJww8Qg3o>tS1FMe1~^zJ|KGWo_8f^Z$| zZ1!Tx2Do^&aJOxv3bjbb9n8RrtF1Y6Y&Kk;w1oYyVGS$p@xB}S!BaQ2iq=Dd-gc|3>N$v;8sfEc zC_RsIBrmO*_Q^6_qRA@H$Pw@RU+-VVXdS4R70iWfEzfMM9Mp!in`FrgWxV6K%Qj3# zm5s}-{=;?g`pp050=%9|0fJVlLvZGfuLGq&^BO4Gec72@t+F`68*`?|eDW5jCrv*= z(rYaeJm??oMpb%I!`%CV!%#5Db1s_as(j+M`|^<$W0j_>Yr-xwmFZ+;43cFI9S=7+ zwP+O^QqB_kh++590Xi*K@@V)n9LM0U8}Yf&9R%f1fdgU zq#gcOUb3e-bBlJk)V@jWA~}7RuqN!bzVifn={r=^4Jy7^Gd-@@1t4r-BsU8tu1f4Z zQ&G%S2>Y=zvW^kz;Xy)G`UP9Wfyq_sR)lcRIyi>|#4Fo!(AXme&{-Vf?8A549F?W| zsU~>-QEi7)`)%8}V2|)HpX(hppYlnDLS>nA&xXR)wnJj_qwBZaCcoWF?RbyF81(%0 ztQ7+?FWWIHrp3J`o1412CBG~EFujfGF;4MPbR(R&)#J#VL(+=;DSj7i3n!$Whyf?( zf4AD~2EE->l0>9nidWlJ?9y2e~vDdRE199P2Bm4 zOXg0VRnWosn_wItU~XKv6+Or1uhvbdV+` zbVNj?L`8~JQ2~+OI|()PC?LI;L&==+)aEGu*WpWJe*j)l0bIX{pW^sO?hP9;d{Xrdcz>ix`qAB0nR^ zThqDxhMa6~3>&;@kP`}wes~{6gjY<2ILf(0DxDC$WdCUY;TIWT%f88dszOvK3pgH^ zce5nc>|8)-a7j(f-|EPH0)*7!oZQ((Z@BT({z^&#R3-rien9fHBMvsrdYE68K)eYEz-|&8azFV4 z&uKLWnVg?TQ3ot>m=vV>+0O6y{rpeXB6Cu3-b6Alc~+L+iAK1QbiB6dQaks*d#7}N z{t2mO?xJ5q!d-OBQrPGAJWiRK@!MQ1axrSY&BbM;Yr^EQ1q7w@Gf(f~^~ouw^_3_& zN3=*i<^2^>E33A!2GrafQHD5gL}0a0cJ;7u725G>&T*q}AC~_)l3Dz~hTTNZwYc9# z`?1lk|2O*ApOK127W#|x;9k9%k*K~nZ9eGL#(nU0XShMYqMs$Tb-qT%%`Suc>(1rp zvU!{YkXTs;I6j!h7!8?!AASaDx&c8t2U#|?gl&2YT0**%X~>o_SsPn5ez(*`N;mmk zZVyHa+treO$3^`u&Pjla->0qReur-Gu>a}s-*#Mqux@~wmGRfIKO$OiTfd9oAfk1x z@)y%<7`m|E4*VyQH8d_<&aK?x)_o8fIC3SA{3iFcv!Ua+s>+*tO zQv-*&ZzXTRIaA}i;UY&55tXlY$8BxjeSvo@s9} zz5@}zAj!irxA}W__~UvJJxo~o>Yde?P5HDGO4XMZ-BvG+*neBbQB5tK7S};UH^{Bs zEsI|(xzQw5E|n{&6qsw9|74?EFk!6w8@m5^RK_kVx#%d`VresMx@O=_Ly^gt-Tc3d z%~M1@@$N2Ib6iDL@(HkIV{2w7_JpnT_x&ZZ?~(G;KZPVUokJ~jQeJ5Kqy9Rjlo2nC zi>i^-NOK7(hH5ZCctdvI3B1xEJcIKz>$wrEHuIu+UiaplDYrK))_$7$H0gTW$>+uV z%qjX5Y>sd04hrby{`lu0F@?=pKMjy6k=NK+I(%i;>EZ!H#=Ckl&9W3#*Jx1Ov_D^K zuIF+@U4IIWDRdfPI`6yDQk!+7yVPUe9x2r|9T#dSNFlXo_a{eMej}g7hl?R?23P{F za};=aa*4<#Lgua)`-8>&ADqiL$zY_dVS8->6jH!Xvdt*!tffsJ$G5XDJid-O(xc*3Zv$9TrVvgE#n?*&{W19MirT`{$yqj%4IwpF}{xt zD%-SJp9j>_xW3m7N^WEn&8-GBS=}lgm-r+bV6#Y|T% z@8&#p7jX~2`#;r<^aOe+)^?B%mT#C=6fP_DpUER)cM3xnf6qIFm4xtds3oV@Z$pi? z0yr)aO06faFg8bx{%$Mz@tMW@%FJp1iFLXsmHc*@r>AniS!w`BMAHN(Mh{vZ*Zj4- z{Wj&j)0ru@HM`4Y{jW@M{YU;*2jq93i$=y!uL*1FswqpTYk&D_3n-Vu*_C1OEDPL9ckLU;{;X$zL<>B>h*+GsmYx#BW#awZLAZN-Gy|(-*?m4z;l?!DugU zWT_&h08g`Hq-olpz7^%S<3*e76fFQ3Zt?d^d&p7y@QJ&Ox|KghEnIKx~ z(ZO8y!A}J~+qE;hKwi^!AtY~O_J#alQ5#{|{L zHLUc2aA*x^QjOm_4NbxNIK?{{GC3T?E88}6jRWNFW%H*4x@xD#_>KZ?E$L{N;T40p zUft@us`UX=qMHYG2P+XBf<&3}l4O`oU}DF;7UROhJo_2z+)q;?8me+&%a18ni=s`A zQue~Dj~~~Rna$nbq1+9>9aiQ?D&SlZ!ht}o@;KID&UhKm(;$MkS42dx4NnSBi<&35 zZLm#rO&V!Gq@25bL!x@Wq0t)?VAwFhZo^ZnH2_LnCcDz|YW(5z*>T@$QIV>gT{6|y zZ!VOnC8E?skiLwaZ|1EP$L8KO$01z^y2dWRJZdS2!XaD8bLFT z=DV``!18Cyn2rcK#RBT8nrPBB+o6vvI>BO3x9DdL=!xk%%65L*#F_Kv<5F1a!t4Yd zYLn<*GTK>Scld5U6nggFnW2s|SFfX&B3QSZct0MkY@cm`GHe`Enb;{ zW%q?Yv+fk)u3MH7iWUiazKQBx-;a7b{rMmK`rhmGQCjWnOxc(KGl)_5Ezsf*7sm^P zO%C@no(C$cI$aVxytjO@`VF^~ZJLRh-9^g^OvvzHfFWN3;q8@()U ztyjja!W-z-zRT+ASbT5?!`B{ljWm}M9+1hQ9j5OBR(}XnV!Y%3l9r(trRET~hqj#P zbo_;~L8Ci+203DaI+CubD}jSPU$mB8X`3x`Eo11H$_6y%-*q43e@}?()l+`1_S!y+ zcd>u^#P(11n5|V{7R;jcbv=3P3aOD2Xi*%Lb5g6~J6-WSlCZDnvh+I15707{Aw+7d zvtx1CWEx3qJCNVJX-juxr>^?toLNG+pM{Ry^aYZZ?E)(~!tGjgF7fr*G3zMFaJiI_ zxW1k7W8v_-XICoC)k&bSu!Q|$HFs>Y{*~M~=M%$tDVwW*0kI5sPUH7!Y zjT_a_ec@MXtedR7`~7OaJx&6j&B@_DigvAXg#<2eLrCri*?=3QL?4VdIJ7j6-S1hA zM%`Wu-gKY++A3Dx72WvXXa~fuS$m=G<&6A};k;pRsYp0?XuOB*<&nU6)97$fF2}db z%|Ra#+vy8jT*qy+h+CYOrm{=pRM$neJAor*^vHEL2$<;p@ToeJ!+K_V8QEZJW`~Te zv_lNY6?B(R_eLF`?F{2siJ6X66M5_|LWNx)t6E`-{w9QnGPYaHfUcQ2wL@`5tk2WP zg@0;}DTeP0u5i`o7~Xt(`-*TqvCO;=_sWqgWB4#78Yv4C?(R{o{TZ^jVSI&eER`~E zPb=;YTXTh6`)`|k@3mX()VHEndLu_OOlk^fRtE-=*qUami{TQN2=WOho1j+-NE?j> z1jAI)jwa+f({mRPVxZQC>_+Yv>QBIQilDbc5{l^nor4f zzi@Xg>$}s`xRBQMb6zTo&|h|~Mqh%SJ(r#G6p_#x)4MeJy|)RtZC*Kxzg_vZRNSI< z%oXL{hj7Vx8)A~dSH~Xb&UHS9s_VvesqZ!EVo=e3Cjlfc0}=giOK`m|bGMMajwo;b z*S}vuayI9p)d(S|Pj~BdnZ^y|f~4uz75EGcK7C{RMI?w4;_=q3P^s{Q*@DS2D?YNr z+szjk+mMQ7?Hwv-cfQzfpqABDCw#uD&e6(;!?NQaC!8<6(PGuG`Arql3@mnQoWBLY z1w+|U`zRmLg~qAA@q7Oqvv<*DJDEY>*;CKu;bFfe+2Sb|c4~8nJ-9oz3MO|i*v*z) z2@u*;{WuT)tP<7I&?BVboR@5@>T()|?3c*$4a$4S7`KS`kRe>Mn^BF6=JUb;Cqi@P zxP-k`V=I6n3pz_`02KJ37sWc)0N%I9rwnj0?eX|C-1N1>89gqanSbwh?S5>n7g@#j z>tZ`)6Cc+kA4wWDLxNGv2_;M9OzuLkj``IZ@8n9VvqKecFVlQlfKeA9FgkXckT&78 z??_YO_xc`&f;@4{PmX;;GZcJeRb&;WIQC=sSWJ)9F%AMvB7EI!s;qrWFyxGDMV+lO2m18>tO%b&VSgru(3 zOdp&2n;4Sss&C$yn;$0FV|SJpch>gh3*VPuB~vr5(3R!T?c3-Fzv|KRf_;E z2SRK7%vA0>=UCj9dQ0F`*YXNIZ*^4ZNn`E&{{FYqH9BsTmQm|i`zip5hjlriJhUHXF3S3_Xo9>G6RYKpzKwmF(LK8C<-$*sljc4X+y$!L&p z9zLo&>*XWyX{DOdOwS(i`-r|A^C4=w!ZBy#{)BUtf#+@_-pK3>rHh~c>MU1vbYN~~evYGZKUG7EsapnYO4+qN)Y-aG}kb1aVhB?cKLVhsPMGR@0>ZtZV=#X4WN_R4e$r$m;o6~ z*24mMa*!N=P^Rs^_R6pS$v%vTjzF7Qll^_*f`?PBvbLV0vZfjTzNT0kt#Dnf9)2R0 zQ@w&Ja=1kJYP~q0Xta&F(_OL}c8fC}x*#FA^|5tz0;)5Owjg770)vdTI@Y`lvw?ux zQ&-!)W0u$WWg*0|>E|i;oNRJp7K8m-VzT*)j}ms%Pwa5*<=MS?kYhM6^SjPvB=@nI zf=Hx08+#xE714t8#i*29wb^Z02q1z)q{XUJk5-Oiyao1(xXbSl}#)`5ymzf1b@!OtcU|=9Sg_iVsM(}j4(AHCSvFaF^@dn+)HR-G7k~e}wvT<>vJkGP%^{V%F zauwxTpJFwZ5r~y2(S`q8eRecQ{S<~CR|SP+tVA^Z3)z6pWv>Kyi?GXqPKJmH2cF)F zCV(3MKmx&u`3x*&=QIh~e2 zu{I2KU`JMh$NZ2=+3wGbo43gWypR-7c98aD8t(U#M17PuzlW4`x3?itDLuV?vh;e~ zbdZYn<5CZkNe|&|`IkTT^fnLh-T%9d_?@ftdVq#Jqq8jqv~{BTl5eB+t=OHa`xq77 z#i6qih}SYIzstbKKfDXWYG6SzNX+g_rNIHx4s>-WQparXrE~)sDj_DK{LJ4vOhIrv zaQH_+T8Usm{pp9~Z}0Rfe66#5_ig)n3_|fKPR!=S5tq@5^RHFYcSu9a)-g2{1qAW#g|(mH=%>th>ke$jKOnd({Vf{8H&$fleJ|r9{{0Nf zE>k1II@X`usk=J)`Kd1{3K7*e=KpUmWchWL=6TVCgQULqI83@|H!d3R2^2{LJ==f0 z-_@GyVo;#{?!QV&mf$|?Tp;_iMic@}fkKTkfqffoGy;>!l1p6~;|AHgbH?p2x*ZAr z5qp_dwdOta!@xL`)TVUvd9Xgc{f8_GpuWF^D>j#I6_pvHzTvNMu|dS>14e8D*eHCW zQT72*<%ie|Hfm@iuI}@%%;GiQ^GIi|wBg*ZEiNPZb-zon+HAYrE0J<(d{O~%cW$(* zq=Pw2$Z-I=k{z#=Q1`%+Yc3L-iL^wfmy3mGSC%#=eO7UsGrnqA2(^(@4Ag~};k~s1 z@fLWHnCLq2`M|*y-XSD13SW*wkakw4p83#JXOfxPl zba6GI?x-b4Li5k;L-%^~eyS^1;I0ds$-{WCMGiyw6X{Ff9F?)&Aw6V&rVl(}-6f-g zmVw3V8+)#0Uun}9uMP;9j06cg{C76O;?xpLstm1f`=CX^8^{IKr9c_Hgssgv7SB`( zQ4cG$f zG~=v8gn;SgqST$>$eQs#n*XN`M&1_p#kcTpdUQY!#G?aa`khq-r!7DDv(&{S4aLm!&)L&rh&O_JwF0>woZlM zqSBX($ou!^j8B!p>+rgqzkja04bTvM5BuH>~6KEx;_FC4* zmU9Nx-!u0GU~$n+oLFK7fS;SDb$1?xVqUX9uTZ-r_E*N1J`6|q(;|3KMTcgEgrke| zdbmY-as=@2|5_>^A3$7%x4nM(#ty=5Xd!2kQP|&J7)RmlvqKa)Zf~kdrl!l3Hix>1ehZu@L@GbJ?klpOuv3 zHXSykzUiG9qcw+%^ZNGUlF9=hd=R5FT`%7!pYph4f1RL?0v<#Tf~9Uor}rCq>!W=6 z{j9QV*J@z|F2PRM>_g{nwXF(p#>2VOEF@|5+NacjK1|*ZV{?~P72e=Ib2sm2#1ki* z|DjQOgP!IQpJIS`qqyr1_FB>5k7 zH>izcHfu?$2QDh?-Cn`@+)ZvL8y3csD)DQ)rP%TaGY$_xy8ppY<@vsP5)?US&B1S1(H1xQhceA2a91b^&a(^I6@L9Y(dZN z+2Ja@Yp}ln#+aKi8_7rIF6T2WP|4C_Na6aMKz5a~E-7;V+}Q5nVXvo-&;bzq;;hp( zzUpF68VqGy$FqcUCC46}P=4|`XiKj8mIR#RD8zg9Q=FV^Ys=6s*=Rb|2jaIEn2imW z=x$k$Ta2Q^q_~&wOuIYZuZ|%?B(cqm3bDd znAZw-SW4cXFiAsa0l`&wAeKu=CdXtt!%JBDKCfF}j)Cidk%I_VpcE{V3wJR0=HZp( zCnj;xl&$MNF=s!n?sN8u@)h>)oclEH1F>3vHE%eV)fZ<4Tr*JS-HM@eZp1C~(N)%y zFaok#GIW@ZkHR-W6MOf)y!OoP3+Z2EBxY&B<(Dm|gj-KdvmC)+{qSYSvwnkW z?G~&{y4wQwbEl~*m+QpRu{{H6L&>*9UN}X{e$Bp#_}<}dj?4`+%IfcHRh)em5qdv2 z#3VT;i1&^<;I%ivO=F9T@P683Qg{+BmGLyhbF0K<#I3NSNvg3Ff5kFP;NW-X=TX{7 z=GIUv%!{Av=-h{O8e7Wg*&xp9&o}YmRj2qJ|4J@IDM!Q_a7rfx+djAhF}-ZDyG+Rp z7cy38pw7XaM{4M0X`B2lYO+}7`}Zn%&9d%A*dO4RYaCJ9W>*EG&XH6 z$^+M;sPpH_GHyc|=yUxkpl;I(%fAngkmkNSUd<0zE1(Nau`{DON_#}NbAb*kv)VvM zz0!{hk~O)uaDEStiuwH!OAam>9US#tS=)bk(f!jyObj(a_)C1uNPn+Cz8fukRm3#?Teje{dM z-OFo~TE;8L-rajbn<^6oJ=;`qaAs2O+6|+d^^Bgc+r?D*LBD-1e#7a&ip;Hh%-T;T zd8#@}Lny^>B+GHcw4wjr^ zQZX$%WHcmw9=ed9qaj7OHU0Bs5!5E>rQh_VWKmAry#qb96za#1>X`NHlB9i+D&kZS z=XY5HR!Yqnl1X=}?+8k7|2(@Olx@%`6i1HGlD$J)bAL;ze6*eWV3rW_ zYdmV>V@r}5^DA3ctklt*lZdx5Y}yAC6KDUypmIOWfgF3+ESVMVWhwn}@RK}HcdwM+ zXf?JTF}6TyaqYhX;41AagNQZ8E+->l`p4ggR}?8yz8H>o&oI~>z*OmamK9(v@^d68 z*Cf`jhPO4#?UN4nvJ~m_IPS{VFyZLfAGt8U8=}V!(PPY{V#xzsxCRMKNwcl`g2dpeaNjM+hHIxeEFKV5*fs!B zMA(qa+CH6PAnK_dop1?igNjKHlLYDuL@FDky5_69IqsAn)gU*eK}7trDb+>nwfyo$ zJJpb|_gy72P@;rUjOl2i&i|C>c*Rtng@hL~)P8?*m1_@Jd%bB?#dbAYAbaCXAt z<0+PdyH-~J(ph;hFS@!DKw;d;#EqNR@WB$eIAX=_&jXemTpZK}!8H_c2f6oW#$w+; z=<~yC002sqS=jw|q_C;wd5eQ^d2;S#fPKttw?NNPhXsx$$9*X4xD0>sw@nzI(%hAW zHNKbd90a6_nfgLx0JoEDi5pu^>32BAl*KZK17(atUKk&&+F^c5h^slgm)TFbUhT|QayFv?c9)6#(W11JOB-vzizO`gV z{rKO7a*k_a?#7w^xHp5Y*N1n!9>ckn;4dWVUS^N*%bbf`x56C1fu?D+7%JoA0`L(B z?TvG9fXq-~vU=-6kLs)K&fORuQC|{>B4fSb`}IDi&j!H5b{@XW4mBHb^P)Cb(P1yGTK4bfvRQ9yz`{#j0Q6R^UzjH z4FcZ4axqYi*Rbj`w=Tpk?;$<-voH;QCs1)0 z&UQctc!&BK_PYHLt{1Xj#wmH zb&xgo6O!jV{G8ilP_Z3l?)w6JmDg><)@ry{3dGvNhXksPZha;!rX_A5^Q%-60d=d) z>G^K*6|EdQWBYm*@L&Af@MAg$lJYI6_5$zC^~0|@Cqjocc|5R_%i93HU_pJ_<%`Ka zhz^ln36(m$A!Cj4{f_ItSJEX?HD(s5ogyGO@DF2C|7QLDi@Ob?*f&oP9Uy+{=B=d-yYmKj;DK5-3K#ORCX7)AJ^3`SF3_}_ALtx zr|pG~f;-4Re<;SGX03h!t-N`GuGjG*E6}4khk??6*Wl3leBTJv)+4?h_TZfVTM7-65Vcw3HZK-^ z#gSS#F=LAQQb?{pHgu$$d?5N_^wFpv8iRMflOL*`S@?6fxoPNXUEW(U^5w>AxB`E` z){cSZ5H4}djCL3zE$ISVsQ7P*L<39Y`2@Kae)-r4o0fV(7;+Six%!u8SGm_5Qc(q& z`?2q?f}h+N$(UK*^)ge6vRL$qcgg)@29N(nT>#Y8CnPx9a|~wGc&Y>;Rlq7q?{o0y zBsNgdGR&f-?pK!Vq;=L;c$S<5=B6F_=SM|;xn&37!;J_=zquIj8SL)hOc^mv*joZB z28N}np}BDadf0l7{9SyO=~Xd-91XA+LP!Q(_pZ(^!HT6uo!|-_`qaK)o%?Th+4J5( zs+Ft=KN`YseUP_ZczG%`^VCu2=A|bY;O3%7K4vG}#jR$$Uzcz^Ed6_4biq<ObLkE`y@hS}%jZb=H}-pF(N98Q-4- z7Ms8DRy}u$B}uS+a8&4*>JO|bbdb5EKzR$Kr}L)nRWy7$8`!S;^?U8+hq?xhH~MU~ zI?=UShb@>qB&LH^_492hKmf?gl5rKYu#|`%5ETW8rCXu30gptC%E&D9tS#A~?tK;s zgZ+GxS?(btZ-(=_X4h0xxMF_yacq(vm!YN3nf=9n z+?DzWtQahLI`@KsE=}B=bO}<>;VY;t%x0?gqpAF_3<>vJ-Xlm$2qGmVwI0U#S4|Ls zcxGQn@_t(5p@Nrr9|MPEcD4>UET?g7akFiKo@QvYUQoC`4;I%AbqVerv$uVpLmEUX z%yxoNvcI>EM?-Avgtr$`C@Dz|8nqsuTIwJu#XGb`pvUlP=`A0D+h9*vFj58PO!$Mz zyC*lgKL4)o?sTvV+eQ7N6O9aS=qQx0z>f1A}e%%n~xzDZ3nXd(_{@u1O?R&DG(Q zT>0J2S3e$-KyT`811bU(QPbVM9*Du(lnPCB?Xaf}n8(JT59t@gI{kppSru-q&zODA#}$Zw)h$-o@c6mu zNWk5cT}6+nmn|<;#wO!esE8{fBL{b5=u!`A2Uhgh=qaSUrPEx{F5*%UYU(JS{ey_F zfPw<-Xb$c)q7C0p^NbieG9G}hD%oqbI`;_MK$tI`gBNdi9&7S{O-r~H!dq^QnJ-OKvLD?)h%EF zFE-v@2bL5ffko{tr`WW<3~2jItkMg&qqz(0rS`XghXG33Ip}gX-O~wblXcBrD_K&n zta=n~lQQ^eZRRx5OE4(pZCoJ$o${@fPX?_j$5&t*Nex0SCCS$+p1s%>|4Uno5MTWt zYO8j}oO+$`Jb#alC?xYkHl|&u{`?fVIfV*PM?ehSFH$ts1@orr`HwSOyW|$wP<|10 zeloH0_Ruamh0l6dbpiZgv2XbdtHq`9jpYg8L{du8r^S3K!QM=Ai#{b=tkD{ZVX}Yw zw8a<*}G=!q9^!{e2122j)Ul65TWVUi^^hZo&R z#VJ7N_YiZeE?Lh(m+5vmi%;0u?(o8hZbcuCr!+3_;h%bIB5~8!A4P{Sb620vTG-M7 z9Brw^7jp~HwY@FZx74Xwlu1|psov%%o=1V)20BEArsq(b{J@2|ofaz*pIR%Cloz?z zj`HTfPycue7TasB8eZhH&$x+zp9{|EGwJ+8nbdS>uZs%_;^IFlEvz%u1V)BqC0NCb z&zG4NZU5Y-b9k3nZAJN`;_ess-$e`W^?G4+Su0h}YSo&T6)>&87Q61R>Lm@C z$Y!cley{buSzT}h`2lzz)clDb**p9HTXdBIH~N7<>h+4cl&YG3m2JJeBKLq({L5x# zP@R;Ja^W0Ln*=%c+K?UC+OZf~FURlp@5+;{e|B?WHbwtI9b*A!N(5->M9-O;S5&b4u)jVF$8m@EHSO+WnqExeyFDYMLeP7=q5a@~QlBMarS)TL10u%F+d z3xcX$P+pp`-Ao9uXa79BeI^=|@uGy=Oz87HOiA@{A3^-+)N_61+n!~X!QTG0kXKa>3<)4@g{Mbg&$ zahD&Gi(hQ$v*9I*%&6FgrjvPP$W8+>^wvCV%m4O==&;A5RlD0H(0^>5GpE%OCk@=X zJ7vZv67#hWMoX}Ajy`&xvL7B|PM_^*56)GYi%zQr&q!%)qeT&Ltv%I+Pj|!kZo79> zOnb}p{5ilYXW)(So2Jf+3Nm1RUkv}e%1_Ro(oJ-2t6y+NOV*!9Ql<75uFNm~#2uHR zTk5X`j33a;%D>e3w@R&A?7BPmvk<&)cK>|ktkt#JZDn{79P;o(?6t=>*5aQ~+-5vR zcmK~DUEFbL$SYejo@Ei5++Plg_r3+-(*2M&7W)~ouQRHAYn3NPHThgG&3E{d zBmm@90b)QkO+%j;b&m^?67+iFS|@;QI~J1l`zfLLtWTjO=D!VX2$vrMCjqB*mS=3{ zC32fk{qO+y^UVnLvAX*TtD2Nsn4gFA2#UdGpa5aiv``R$hyT)>Owpmt9V{wb=Lm}u zL6h#_Z?6Ve2AHKjGNKC$Zg0cmMXa!2RG;ntrgneXO38`oSV*mj@YYb2+)#YKf41b? zf6`EDeCV`HLS)DaazS`yC9%C(rBSO$kzTqQB$2Yo0?Aws@yHxpG9pJ*6fY*E+S&mA zUsvX0is%fIT13dK!$7{Vi?xYabcEbycl!a$H^P0?E)sqR;Bk?ApOGVk7(CaT)@Pmu}kF(*z(sDhioh|&JfVR+ISsg8DBMGpD3&LSHx%k5+<6$!#@2Z(`clkn< z(b_)_G`}D`nH;AjtV`Eu!VWiAb!c;l>*vXlnuxlcE!b~}gITr6MAELJ%kb-uDlnV4 zDEqC{NU=f2ZEwr+vZB57-g!>VT!asiv5}@3B>!Ldy{9Y23}tK>SnbwVMp_NZ5&l{fZ_I5x_qKn>EC|Q4*eO(?7dCtt#XM^nNq1pp|S$K z6g!>NewVI``pZwqiZ4=sgy!{}2|c)&`#7nI-RayhS4K&7(;$eeY}~auZ6%U*DN;Em zP6fZeM2gLqk-;a3yaG8s&$>MvlAVi36L0$CLv2S%YA2o@S}+deR^cZ8y=+oa*k2&y zZOgyP9s{{{LIvaLKQ29D1q({D;v!Sdd0{xK=QBuWHfwRtTT+TBKnaRX5`x*V$cYWI z99#~b8onkjndg7uptGHP;s;c7sn$?%w)@v1=fu0+=%GSunD!2v$4&0E_Ie||olb{3Yl;>(x(C&xAA z40zz)##Prv-yTymj(DU9jNR1|w+;beeFW>>7T>c&jr!?W3kx6IJL`THj`mbn?6FC5 z7R-jaPeZBQ)C;&jA}easL|3}DusJQ~fc@p$(43an@hR?LV!3}+e)sW}XX)s3)%})wiHTHG5GN2q)DrfrAwYr@n}2Oa`a4Wvh*~ z%DedJOeTN;9fZky&>NEsBFwtpayq6QP(t1HE4I7$^wtYKsye~2EE7sWc_3rRfQsc$Id^ce$G>O9hbtrhctqlcucW^E-3{z@^i%A z?$`D@v)D-=<$*7>NeLyL{WeLQw`W_e?rphN@FA=G$(fZ|4$sCX1O&5I#>;VigdaN4 z*V5KB#U2w$`)4`GP0oGb7&yK>Xy<2y#pTIJ+5^EFOWc|B4Zyl-+ijk27r>Y@G!6~~ zx8bLqHNG0~!gI2no(CB+$eaNX-#)|rjv09N9A4nQ58l2YBuEhDN%ph71@R^ANWb!f za!p*eDdpZ+3oN%skte`%6u{&(F%XtmcDw)CK8%^o1@_CBs161HSwp_dx$^8=rr!2W zV@Sexk8M?(&xs)T&(-^96fX{f!tRLq|Aibh?7`%x-KWCDXPtlo-KxH766vm+0w++> zvgxcW1vOQKoV^7S%UF!i6bkkiloSlM9{+*O9D}DHnp8auDHXY(&nCESR%X$<Y$X7Y23MsWEj&=6$Y=`CzJeVzaNm;h*=x_^_psIRR5&k+dQ=tmW(gw$ z4rEUIjaM!C<5KRc0#n(!cgqnmRjuuGwvGn$#bEXuptrzi#;g624I+!cCt}T4eAE4R}G`{*JT{KnH+wjqq zbdI;CAcuAE9K)2=Jikn|pgTsvp!FB*kJyc&(DErHW{rx8xRJQW3cqpRyC%ILYucIs z572cU#pdv+W~btA2R9yl$*HX2^AhN)jqMhe-A6WM&az@Fik73C zbgyZ_+IfIgE&>?}1fZrp!0cOkWQmKQdT_yBr&B;fgH-K0>J8g0NS~raORM&-Z|nGH zTvb$5LsJr2yAH=Gk(Q)9z$tr!z|!QS-wNw0Qjn$;sduG=vK7`mteMrkU1t#P%|><4 z{M06hI|?{dN(I1)b%;ct>$&*srTBhR9ghzhi5XLE50j@^Z(@G~F2t9%QU!)gzEcqv zW38mR{Ea~t6Prmt2NN!SmGkNGu@34O173b`KYf=&ybW%9?VenQcln}yLwCsqu=_bW zv5Imt-hIsD8=hk#1@uM-n@P3rptqj|OfI8Zf`OSW&LZD)#k1h?k``NP?~ zvxZiN8B!;-!?CfZJuC%5`P1UykYUd4c$;vcMB~eZB8Mm6OO58S?sz)ak?=Yv*nKrM z;U9bS?OMQp$iSLnA^j+yYJ2%bR#Fe2JkM#B@FNZV5Z;$JPtfxSEWyZl!rhVS+6UjO z$q@$vfLH-_rKuGHZDX=0-HKigchgEO=keBI@jqk4-TLv}K;WFtr279`@?5F2cW{@; z9bw|i5Yu^(#F*zNtqYiC5vDFItVzl!qWWm&4!CqOw_4 z?&EzKzT$2Gj1F92hdY7lwvh%3J0^CQPZlb|ZbyZF?(b%_61WGClpa*8m=Ud7ZUh<4 zvu3ro)f@(%fpC&3_FkAE>T^7mky&wb;noF)q2NHj%ZfohooDX`biuctOB!NI{G>ZO zA=O=wbH4<(aL?Y6&vWZlb_(i-+`*y542n-B{P3tbfphbwi`tSJ>+ctIz=cV~z?b&9 zN_`25A$Ggent7_d=_W^{ZXx2s_vclYB6;{M`)MhM2sj@<)`F}4Tnw+h_w+~as#O`N zP1Va*OZ;T*H+xeAjx0WH(y{ros54Wgi2y@qAp{m8@|GihpU*pn+gwcqWfQni{u>{f z07GQsZ9}yjO+TqU9Uce#*$jc+Org0UrDt+I-+TUw3mrA=ye?@yW3K+ZGS9dc1u&93 z-X0&{v2e&!ner;=?~WXImSEc&%=+~&>C*h!1X4iljHK^GEx6yRe12?1-eUb;|)FFT#TujRHu zo1X!ejsxob#O9>z316BBc@|ZX3N!@wDJv1S`Db7@Sv(KlKlaWIY0!VGg9E*RRcyp1 zKimi0ln2V9|G)MMV2G&k2J-G@ASsm@7en+JdMZjjt>dOY8$%hDVPU?VEJfIR%oD^X zz8L)EZ&&vhM?>?E51O6!LtF~8)AHhijOCRlobDC5JRlHmzHwz8_oQ=7eVkr_ z!co``Tfu+CSq*1Jkh9v_?n} z#YA+W1Wv*N^Wjvd%PygO$E{aa!^duo?^Kor8Gi_y10D%i{|DY-Cf3FRNb2mRDQ!Lt z-?FXu>|keG9(v;P=hs4h>x^6+3VJmn0lg$J{WlbY_Ch$+nki=$#v)xsHchyI*! z1{s>TIB^FR7mBoMw5sTuj-uF;4+mA>ttwjMXyaLUmP>$CxIf-#hD2A~XUt7eTY*59 z?o)xtwt8T+)|4^}U08E}^c=cidFhtVDW|c-sMq_{xm-)n*5_6>8^3)U$U^LkywPqi z&!7{Q?X_BDndE9tDSsD-!Ea|WkJzV~XJ4$q-Y z9qp8fqaTLn@E#F7lKoL*VJ{A+N~~&4>x$Yi!pr70mQr!R=$9Or%CgdQDEZgoR93&o z2YeN${PFDdJ=*IROhywOxJWX0qP8?^SI45p1H_OOIlIown(}k5Go>_ z?r{OfTKoBvX#JFt`hub0qLer0usK)qO|HM=lz?jifMnh}M$I&wD>p@dATbj*6yYyQ zv!{4noBR#J;GQ|SCga?NApI8r88t@DX(pJF$IKRG&+ZGqj)b{mSGCiNFEF@|R8KOF z#y4;H!k$D}W&&}A*J}gZkntQ@g@5D~HO|1BfgUlaGntUw~(`>vLPEG0}3$u}5=51g*njHNX%^;J*!vdB) zmjYO)=H#2R-q!&6I%+YFB7=4b)!cDN*-Zj9lsh=lbjm4qXch*&lzdM)QU1zf(m6BP_CrDr znsKt{Aaxia%z|4p`L;kPnf~*i(-2;YempzX%C|#~SnWGbC>uX_s3;GaSVG{XrB{3< z_~N5kO%*%aYMHYz8x8Z@MOtL!n{=AL!I4KcA>(&=h}NY? zFYx5KOq2{1**?VOs1?v@28*+D4={WkU|hpt83K*xq>K151JlR%$-ZS&L1&uF=pd-n zYF>5v&kBeGoxZDro%Rzh-~Ozy5+1z7PSzLZuM0R$ik2sy@a{|*{0d6Ahd<>V)l(sJoY zO$o$=y_l)Iu5Ek@Oi>N;r6#PV@c;QK!Pu9YH_6Bqr|@twH4fD51!q9veA{gb_6G~C zP6K;K6fW`2V7}^8L}DO9sjSH-AjoPrZfjtk+MlQi{d(SoKR zM?6e(h+YhTIB=pYT=-=n;%&tI)?C;yS1~dd2^VdD@3o*8v781 z!Vr=2fBI#&-&Q!Dq?W0LyPl*QSow~3OpJ!qE9Ow9}*BHIrE(v#gI z57*tcXi_QMB6Yw~J5AF?WTG_-YO@%K=m24-GB(T&l%5+fK5fc?2VRj+vRxRjTYI;g zhi4|@f_=PineB!?DFI_wY6&|=yi?`x8Pi@Eb|wSh59i>woU&YS23!ii#^<8^yq}i$ zVl4jCWIk;Fy}P-O-?jLfa{t%QGt8q+)zNT&?#=xV*Sj3?4W>mq<*Nbr4X2fx1)VHW zS;_?gXbz?Bj+d>Tg4@bQg&vEc7*S7w@#u80<+|G9Jc8_-;{*d$2RG24*w}QP1oK0& zAmYC6X7IMZde9tiIG3}U7~rlnLnCJo8XrGXRb}>TTZx&p{_-T&daS1c(PB;W3gbb= zVox=ABEZ+v7RpDPnS7E4aGAYS=t6R!AG6{jn9hBr*EcY6=<(?fy(#9mP+zu5z;TfW zwZZ*Eqg8~p4Y-kFYT?`ccnSC6=aF89%Xr0?T3YPg-^v+=i&AmwwF8t9Ei|jvVg3C9 zP_20#dfUA8VcSEtddODzo5L|X1h3815Y@f-;NTIdlcnl`N_R{BqrC>L1Chs}O{tyZ zO#Q#!uC)X?t!rTSYw^a=sveg9a0bduKwrqc!2C(YS#N)ic z7$ErA;#=_oc5?z@);dbZ?KJ2}N?yw&ox@e<*}0-oB+Y9TnaP*DFgW&qm`A9kaHcFd z9EWGGuJPg>F5`F}$s~_6-DlbXi-A)&*6aSne>a_+?(?K83V36P6rQVUabc$g-K%^( z4gYcb;6~aSWv9-)ht$F=aCjl-H3~jr9LMDOO*p?wXd?4#n-p1Yt1djZbP?XBpA$U+4a$LCYze{B2Ig*lvJt-0gdn^@koi z7PF|PRp-pCIk4cY*)>7t^rbzma*PE5B!v{&KJheNJUIR=fGN&DU1@iAIeKJrNX9AeX9VZdsp!$b9id-3124dV z7sp;Bd8CRrJpHr1)QgPg;$|3%`tz#}JJk7ytz6?K%H2*$K>nlV|3lWBzeC->;loW+rVw{2l-*~>DOkaaBCml?#^N5oiXhOuNF3^QZK%slV=^L@U@@f^qV z54?Z4Uf272UDtV?uk-v#cYalmx~|NpFJgH=gg4M4pn@LNH!)muc_*brV|rs6dWY8x zJ1dV-7X@_X-)%Hrx;R?eEL<(sNYr%>TgQwzx)DikzpC?$tk0}>&+EVsc2F;iFOFHX z{4;N~i#&y9&dr+LLaP1=dk)pQpxH_F+_O8(eV{dC4#-A^u+m!&hCPj5nLY*R` z!#%51vLu8Us@Ru*xih5v*$SB-N% z!-Gb@pCEx{=uNVdvz*UR%h%89kjD>5Q)je%G(}hup7XlSy@9WFi-!Q@Y|e4MH~ucp ze1W@^v(G`Hb>taTipAXW&)EdT=-J$#9RKW4oM&ypxTp1h#d*D_m7eJ_pV*uCSep_V z5x#03gk^$?SBqHAGc59;z(FiTtAmq2Vc6u05D!QWJkziJBj6N&o|lzsRP*pj+0O3# zKV+~MI@;~%hHAQ}>N&`ZPzs+Zmk`Y-46QX}Y0_+xP33iGsuhdE z$oT=rOAiBA@!}`+M8_6dEM%PIo_5!T>oBa+RE>D(dfE*GL-NHO52KC;uD>Hq? z|85%;MLLLtgsU@e@b}YhDlAOL_cjY2^b}{I?P{wGk`-o7^1Xgsx+;)AM)BG!UyKn8 zwlSCXHK9triMlPTMTsb^$6dQ}B_&QLSTEoWT<0%hw6O5m7xv;HpO3^w8Ts73a52Z+ zrAHPj84zh(LUGT{uR*}tknZ*`R`scP`FvFRX<+NG3WVbLe#aK4lssbVbi?SoT6~a3 zW3BSiI@R=0-P7iO<{!bQI%Zje?o`U2(<=2hCn|k;uU>7YLZx>D8+A|x%G5q#^+`?` zSU6^;+_9|g`KjH!*W+En zqeZd|`k?YXmAWfq5`H*eZL5Z!ptgK~GBkD{8*1guo4DXcs7l7PG2rbXXkfPopp&d|1m*$Y^BLqT{VrxS{gO91rRWy0uZac zH=vT%d`BVg=U!S(-2Iw8v;+=hHA~)@psNPUZSy$H-n0O#yO8QXVJCto2q_sFu!Owd3=gahuNYjl(E%cxC; zgV>~5;M26Be;QnMe^34Ye_tCGjAA`R1Lx49ffrVL(trNhQ+*Z1*BIJU{Q>BmWXUxV z3*15%Y(y66AG&Qx!7XMK{qCJOwEq!mEwA=dlh};G{42JZjH9Cysl;zl&avRiJY62E z+z8N8ZDh4(qc$JSn=L7D9ol?)lDorab{sQA&EIl5xWhsJ?3%Ipw(=2HhLv-O3|rB} zFP-1HFdr_7R{V+_7auqG7FZDykRKPFZ4TIni|BXpCl+t==ShZjfp$V$Tfl}WQU}{C ztMFJgJ(+u8z-O6en(aCwX}cyKzxymG)XVfoq-dL>YgvKShvQW`ZE~OOIL^|GAf{kv z;Y<`AeezBu6o)$}wn_^gW$H3tQ>(kgRXXSq+-5=zx-_^9oq$vm(MrbG`t38O6$veX zV)tCbWXrwe_<*)K5GeGDq%+Hrf>c?If)?14^e!OTsp!4P!M(L5zfg7FuV$a_ahHV+Zww)#-$90{T{SU!0 zQB9bhm$&HH{JUurp{<1>&m#drsLbE-C2!s@s2($5r5X6W+|?dbZG{d>a4%4Lnh>qD zgFN*4$?DhOoMRiIZKVnhvVs+2`(dBvlWmFJC2$j*ySecG9H?qR=-BIMy?rz-5E4vQM)BpTu@t3$_2w40PKN*xJ>ps-qVlU9TymN1p$b02(HMM{_3RF2;iz8$bJy;~RlJ0ENG| zsPpDPSqE6i!kaA0o*i|dR;=%Rz~#OTDPcr8aCd?ZV+>azXA7rqj+FGXiT4jjovr=F z-lL%3&$Y9@V#uExVp^>NctzO(E&Q)=+yS0vv&+LRBuAPse{OWK2bu`(R8sIOft{Bc zwp*ineG!NDs8}uVedg(3JH2;FHOtWS6Fu$$dct)aK{ZM-Gs-7Hc0)NrVF<}{4a&{Z zAqpNDo_u9*|4(hB1wmRJ7gegd3Z0EufQok3ke+Wk-Qd}L<9jdgCrT|YYTu&4nj~F( zGKRFtWj532KetX!uGyEHWOI316QtZfJ4=s3ZilwWbTNMlu0@bxn-S_TCH9*`J~x_G zeQt3c%lcyLkXe`&MS;Eg(BcQ#&(pF~ZKTWb>ZOo9&qb}%Q3a=i)iHAT){CP@CV#Gb57y4N9&C9J$4NAA zq5D&x+hMj@kOTuKXkwGj(vZ!h-aB@d<@gzOy(di`aGc*QxfcFLt(FeMuB5S5+wg_w zM=fXULL18ob)fO;LOoV_C#!!a6sM?sQ$bOYjcx9G-kCJJY>H%QIoFDA`xa^1zZyV` zlt7)U3rb@~hzvmABa=|HlZ0z{=*Oi4tlGSK%jeXaL*lH&C zg>jZ~|K~80PA;UFDgayQjq%s3LVud;3&I>ERK@u@N~>}2kSlbY9b)y8zI)UDa`t%e zF_RP%)B0go%US7!x$1kA)jQC-beYg58P*zcdO$JiC9i_{!Q;i)0y+{H*oO*KoFa_P z*16y6ciu_n60+qjkS}W8a`LFHH87n7TvTJpi*Tc3VA*9d)>fEBoy4;uJ}2*Jh2R>` z@QkP}l5#2?Gq%FkwX)NO-+hikSA){a_pi8ZRO&fyj|3!u8V^pCCZ0Md8_?Lyo4#JJ z!TDo(zu2%jd184dsD|nB5nkIlw;2*p+~9yT#mCggt(D`N{S}+9cH1abkri7?u<*(D zc|Yx!VXm}>b@!R!6pF=8T{4#$acI5E150;`;p@qgFs5WNpB}Kb#al zVp39{Y=grfCYBU&4VYuM) z|0Vg}gHt@hZm%xFs^H;qWhMhNpGb3Pi#knZTZ^B0oY#yfeK3`s8$3_?(gHs?eQw@( z@LsdShu=527ZJEKismad0AV~T72T5n$7v5pofCs7iFSf{LXUCgX3L=T4f64oesyOQ zf7UOnwj*j}onmP?KkDH2KwX*H**n6v5`#?1%P<=?-B!{K<4&eAMf!7B30I}(kp@+ z)=MOu={_4ZY{YKErd!z3h$de=n&Ta$P9fS*F>NM19(U}hf8*_`-^hqfl z;HhB6uKMf$7(e7$fY<$qeAi&2f8ir>Mu!Cp=d<8jTF$JN?`@lih?^|LH;E~AHyWOC za=?h5Z_OCnP)(6zOY7C8r65c_yg9Nc*D=w_nHR)PD*H#G-a?2|+}#dPumNeNxX*EL znpfN+z)eSid1`Rna8L{nHF?C-ssp*gD!;MgJCLrnKJNGt`x2_*&9L3pF6n~ELBiGQ z)?s%fvlB074!8W{Ub?&DL$-JPeez_Uc1& zUJvudw!LA{@u9+I2&P@|-fd=k)Cdu?OONt7I~z3}IcP=Y^A>MPZfuqlqxA>yy6tfu zcbNZL8cKZ&XwEpn4l`NH_L6g*d%j29FOXHXqJxyEar%%;Ya$(ta8EiLn7$a70xRg^ zd@nygQnmK{VgzZu!6n?~2>(-KuINnSpOWD7B6SHB>EjR;c1un!c`^p^wZhbB`m79` zV*ExTakJeND|Cv}I(5C}F%F&S{u88Q@Dnr{CI{I|uNR$wiH5w`I<$dD3W%~?Ctres z4+>{I)$@r5t&p>dp^5PhAC#AbUgBfkimZGMiEim8UEgiO4Zo1GpbIY&LZfbnkZ)LA zc?HrJ4e5xIGxYmbqer;Vh0qn%%42c%G;I=&GDu}{H-eckbe2`$9_a}j#|zGn+)F#S zwG-9@S?J=FLAOE?FAw@e`7{|kj&hX^>o9!-7Qb&(Cyln)ihS(N?L@h(-~ZB?yYMh` zF=Z1kO;h~!uKBYO9QTQ*HGYqR6&BpU^{xu+ZDPqOJ?L~DOTilG`oU74 zk3(*?7ge-K?fq-45_{=##&dFiv0Y(fCQ>BXiEvxVyd1L>4(6CSw)ccr|GIlpAbji8 za?N9$9;o|+{rcI-08s`R9iZ-$Kj0$wZjD1bsC;NI_;y{HvRAo`QOaZK^7K624hv*c zqFLC#gNolYZFaq`@t?9K3!Un)Ow`Lr_7t`-iCqff8>j55S>$5SP3gPTMZ%ch&)oPn+rpu#hcypvO zq0YW5Yea0%O-rD018tm@ZovMoGkC2g8?z6NIPjfYj1tcs| zO++#T_q%8c>;bj?q~+BFMBoYOP5p29&8alN=Ae_G~P&R>u};^(wo3fX$DtpWJ=6F`GLq zx0>=COBs_V#>CAImrk8z6q zXaAWCcRVTb&4M8sbgn`?h_CgE^Vv&!izsfzz9F3X9dIai2BV4PybXa)hTvw(JdP+g{{3X-EUm5VSERJw z#%5g@j&7jxTpmii+XZZQ@$2AH{l+EF>lcDWOkqQ*3#32O%DRg369U-X`9)CrH=;=e zA@b6d%@%uUUsU-tX$C8GOvnW4kcFCW48wgjlXKe++nvM4T&+dM;?)DiA5tIEzxVt1 zuv`KDHi%-jQ*e1L;J4Y(V!7(J9~`%eJb4fAtG8_! zd|LY^(k4==L-88XTIvi1Rgt)X@s#xCa$9A6<@{tA$S(vbj4i^RNESQ7b$la);A=TV zYj)`~s#Rk_?K`K+CjZw)-;(xCPpj8*9+5FAz>rOl+<9i3AK`#^v(U<^9R2T{NDgax zV;JF#)4pIIDfiWc%k4QoRW56 z-0a*%g!(fL&~4mbiqo-k_q;-Q2`NkzIR6qdaf4B=x4JRLRxr7gxA}9^Dvzb>Y;E~j z*6>4U7*FJxuiVvFLd+=5R{r#7_L~*PM@-|*wU%!?>+7IJeD-KTWl9P{&*Q(+>bCrU zOY2yuFEw1?R07Zy#G$~WVQiHW3=j5C-$@<1H1X^qTrh0`~8~469`L z>@s}fZ<}96>dx5xiSkr-Qq~93bMz84j^hpYKjkSkSu#Qlki);dr1(JYPmW~y82>2x zur3QHfm97pKgDXaiI|2CgMdbB4fT;8?pB1rMIv#&!P|z+GylsS19s-2-P26XM&eZ% zXS3orS?p8M=sAIMWjq2+T@iA@{eoN|uGxfi^bi(= z!J{Re_trykwhfEw;r@*-4qy@cMu~~X9i1Ev7VQS)P3CB*g1}VJlr4ejF>DGaTPHHi z8a=ai~lU>#fCj&-T#Is2MpEC0M-v|0 z0NxMr^P$D{+|!Vyu4R*^U%a>Op2SE@RK7>Leff;Ygr#T7~tmYrSNHc!Ge<#Z7(_O#E z=)>X7A9jMjVxz5EvWIu=F6iruW*|{b#Kl=;qa@@$yG3Rrc(}Pdj568D`LY=?Q0UZj z_yhJ~Eiy>D{O_Lq^Q~bK62h+Y`fyy-iRbM*g$F{;N%aJ@gh-A=i1eL# z^n!~?-i%IwtfJ%Rd@02??q`AYjNR@Z?BD>mVwJr|-n+Rs6Q8oT-(@P&Or~f-yUeNC z?g=KhgCqv%z80TLHw^agncY6ZS3!wP>Z#QIrbtC!D z0FH*qV%inRO6r34Q~S984m$yq&NQ{qkq~;pczI20Bld2z-fNAJzt%&sR#@6McQNGl zCin6)H0*UGIS8Z~agLYSGgsH=X|>A)?VK&^rQ${%-%6yH1ik#<$p^b?S28-N1;bSVv2;z^-8sAc8N^UcdQRA#&Dd|-~_Vd>9``gn%uw7K5P-{#ev zuknbSpD-`O7GKv1izg^*6qMK_?H~5_@5~_pmRqLr_vlVY9>Up}&!b_3&rjO;{7#Fo zy4!!gIyZwo#G1;;V=k+gIP=yeH*T~GzL<^fZy7u))RN(T?j)MXYI{20T-QaeVn*_> z%jEO*tv&J-42}|nUTwL0DYXj?AOBJNoG_5A!`W1a(;kMOG827rT0oNYVdRM7)1T2Z zf~R_=Dxs-T6fp#!^^Y2b-O%#4z#aj~7y9KB4~(=f$AD6A>!vO;20#huy_^&Qp=$*F zhEp|)8^LS*NPE?VZvAvrReL-nf-C7Pemmj-p896$d?gQNV;6pM@`N$tga-z^Q~V+| z!^urHzFeuM_ihB|or|`zNQMrqnG__#KLPad7@20#t0%B_ZGrXfJhSdvtggV`!knMv zh8};%{jQTZkH#1VfV6&K9J7cSSYJVMH%DkfYZa9ENvU3T6FagvUIh(haQdI|e)Z?f z7%HCV%8@JA9eHbipY&>Lao^&$(N{SqW0lW17ozn)n~ap{(^v|pn|W*zY$GcoZVjgtKs!I@G*8}ij#N#E<}wBW;?AUdl; zufcC9;tFVG3c z%PGms0K)6&Ma~*)?MYzE01sI{WEhxqKe8mjjdgy>XS_J4^b?|_{^F%N#OI|{o3WLV z?^BtGPl(0geCA!BTMl=S%_soWm1v8~y?DQjXf$*D6x|s9ud1R*IP$5wbAQn#8JJBR zm@&l0T|XsH5{ zbHeUyi_^jkF67;|z5Ghe1b(-M{$nj7^g#d5sK&d(*2$M)<;@~qXt8kVE>^?nB2tL2hCZ9`| z^K?BK>1Gy3EFtiQD!$($rG0_)v9MP~rZOLeQlF%k)Xmp9(fE(`#)%9^SYTFG5f%_{%f%xgelCAcWNHF}3Tcuj@%oto4VDW&To zCKtZ9vhug_H1SRH4I9^SAW!egE5s_lnNI*Fk6Y|brMeZ9g^Ff$L~|5)jV{Yg zv6&=^Bb*nvcn5PJN(VOlAIe^sCz*b-!)^lMXKPY$cFpWh0jc=}hMz+AqkQsarRkdR zH2Lfn^Vr_MyIp;_cWdqi2Cjy75 zCxViH9&QgS=FDk1gT5V-Rd*yB+X^Os2Fiy3geTWRTME*d*n?Z|ua*|4Ec+{9$paqQ zo1Y_gOQ4hwc(wcO3(VTrn|7?%i*>q$H{hU3brCJMz;f7zoKv&zk_KyKoeSS=G4fwx znafx&Y(M#Ghd^#}uFTTy+}`K5Fhw))EB=#!auVK+I8}zyx!DegH{l`&kDdsMYY!;2 zh=;shGIz#ZpFRxctzr4^>U{8___VSCn#`Xt9Z!Q$T!sKfyHuT+C|Y(LN(pM1Hc_c1 zA`gg%m{w}57#d;~=KW`owWk(^z6;1ylD(OLn8MA8>fo=;3ZOT+7&nkxcnpogC{E5s z%{;7+{Ni{n$BEW6TD$g{wo(X5>O}lAwpc_s*RLhQGLbC5QMtgJ_#NkG_6I71?^!e# zW}*LMDSpRO+7n|R5f_6w%vRCS;3p0kVs_ai8Y>z(*X`Wy7u@VUG9RY1+GlJ>Tshe1 zVyze3Q(7I$kSxD0!o|4Lp*r@Mpe*{1^S4v09aJ^h@_-tcKxlo=&&{v2+Ecco6N%Z$ zSC#WozgCy{(zhn8vDi?hPY(xq>5YeAVPI8EJ77JBDoe zR_70W=+#WiK>t#G&B`?~D5X`5uZAh0_RkKrChojbUDt~V7_kaAS@o%Sw-9pisTxIn zk+ND9l9%fE2FO!Dno)x&zz`5(>ILJNYlpC!9igWko8-GBxsx%R&rZ)&pXC5~X?jnc zf;@>%_ihg#6cWGW!#pKKT8nKs?XUf5>rw5;oi#tL7bD(2-cu7GopyHNj&dR(wbY7) z(gOLJj_v|gw#+~3B%^~Qjs_xk*y2jmzmdfcTg%w@#S`d1l` z_hdg9CP^C~+bxH!|GInJgA6Q%UZ7n9Th>Ywz~z5IDbwYNpMG&A-QDq%{BruKqF@uJ z^cZ(&pTFq{m5#SJh%}R9Z}4I z+o|5A)1QdU$=Ita^qUy`hu1T;jcXjV}HNbdE0>%7<#eql?RBg zIi)J1Ro))uHX|%wT{r@u7m%~sfQ-mb_A2_f>fEbFf$3e(UxiGe3UYXCB5AkP();~8 z#ehVJPvwb_;oD?ZH{zzgo+O5817z`r7EP~zoe<4?>2=-`LWR%*WdWrYlLAzHyCd^+ z&KoeyBlOxeC4rI(Dt&%Wz1*=ifuhXbM^qm?!=yqY$@h*O^nv)>km>R9Q zPlB`$NyKk2sN>{GnG0UK5^o5kVPam-tv7SkSt)#_g$jHqcCT>LiNN1GQuD|LGF|ir z)JtnW76g;t=Kee-7YP|t!$m10nwSop>}w*{WaDP$wn|@58RoVqSto*8onUCT-gtl- zrR?N$ZNPf+VcGhN(Z}&1(G|b)$g%69l0&FhphZb{l4HA#o$qX+pKOaT3J}w2v;EMA z4cOb|v^Jw3nu9ngDza8bg8&UyVdayMEGHL6vHRlO*pHi)8Mquyo$-g%yb~o_D-~Ax%h{Q>?wiIo zQJQqBuQC5xOpO8z%Io(DhtQbsMEHkQe&rlPbw;Vz=ETIKM}QXkPSO<)?|#YepOL3& z%`GrC_WZw0XaVyE^TupyFnB`QCuz(DbqL=e5h`2mto<#|H?A9wLrB;ak5B7|4{Ac? zV-_dau8AObR#AIYUOYJv;UYb}sZz@wq4cFs&V=in^ZHw4Y!aSPCRmdX;~4OrCAm z;67?e3O9DVAW|p9^Z6!wFa0@zEh7cFKfbdxuTIgt==8S;>lE5Ppjxt=84hN!Ke*yT z_)1YY1&+PIFk$tcdNShQxy^>y)m;8PHArDkCi>Sz8-AdrDAuUjH!(R zaZDX`dM_Sai;|oHj?j4OSD>$1HN=bgdepP3HL?H9k%cdYlI4+)H=XspRKp(3s5@5; z(P|eC_0gkuIvrweht^GmDrn*nL$}qPjUAFuT1BPxswQ^n9$D)t%v>WsSyTeUaI=9I z@#jW8cxTVL=$YoI;#KT-xsz0)V(HIckKs63=32wKoEcx+C!{#ZyX)Ym60ghvM&w7S``rsE@bvrgx*C!D~i);QI({W|vpZ4{> z{P|^k9Z9Keg=n`5Qj7wDb)Jeoiv`6?HUw1j54J`8Lb!?zY?|2PqRwj>Im@DBf^`~! z%SS9}FV4E~BlqC;fs<&7&i$@>TI;`~so_h2mZhK1)jLS)+Y*1(4P6R5%xlOjnZLXs% zn6YFc>5IrbpC`g`u%!+BBFFe`U6oy@P`Tm#PtFKeC)0m zc{cJqPz}!CHoFv%&+YQFl~zkRF8--wZAs`|Ez0HMTTtR?kzT&unAE3g?xip_fvnl&XBY36pvy+r(m~=T2)kp1iCB>#j3fPK(*DDnVHd~&lL-^d%vdZq>Q0ej; z^JWqHf8c(W4R(P3N~w;E{25WAW?4ezu&vW@hwdO_b$w{z1@!$-;^la&(N zi!KP%4t>#u)iE1&+HyC<1pd(JweGr>FErtb`P#q03z{a8cliD*6DErge7paj!M(J- zETodW+!KDa)_?P+N-bl*6Oq#LRPK+;y=x@mMF7kF%_CG>Q%tKQwll3I!IrOT@;XCd zYux5R({uCIJ@3KF6?b3px0MQSO#(mplXJgz=`p>B;kd%%ABk3*NW|ZWYn>8Te*T;L zZ7U*7A^@g0q3W`{X11i6u z6Xbtt6oPntA3pY@#3)d=&Qn*U%qQLY4gHcBYO-xSpnK0eBD~3WFCfwtww4qt@I|yL~fKCd1WZ`c<&&Y|B?V2m?PsS%x@?>$e;M$Qo5tz(C5!4 zMJq~{?+={%|ArrEG~B@Je`Fib>!Ay&_patoP8|^UmzO-6(5Z7>mZS`A*qxr{2N`*ojCg1rCI`YY@m`@<5S6~Ep z?Cpwq89dj{I!)zh5SGUH?^~jGXkNP=IgqRwY~;>b|68rIA|ZDsek$>GDS6+Vdvb^V zh2xBp_nSpu9=W^YRf<`9oHNW6SygjBxa`|<>-pTHf{^MFzuF$tOK9Yd|Gbs622=A8 z0@v(>YDNiJQUA~;R))1iv`|7dm@{$wSAO8R3qKF&>55pZg*xSre{)BIEps|@)trMn z^ZW`%f8=X$vpha%QB){6hdNHEwG(n}zsh844oAo}LR&_Vue<~RUMyp!I1pxA_|!o3 zkGm%=zZ{oWK4|ttS*~gbu=4}#EKpjq>Q}HsPm;V&#dm_@(;~{l@Nm69#%O9YRo!LG zBm_66>d;1f<#x$y`Hr30j1}i&$RkLgxR32Q5o?7{C(QHb2pQ*kOkH{| zxG|5;pQn%Uj^|ABPuMi!r1z=HLX`Fiyue%tc5$;m<25niDy`-yR;b}uay()F^|s|k zS&pILy@Nd#QX{q1E&1`GCS)C;FG?+rIktFsXz_H*t?4ffr@Y6`Z;i7S7C*4K?aywq z0m#1-?Z(?(2#X}SE~GPF1vNg0@*V6#4J`eUF<-~R;@=?CG z8Qx-{qx643<+mW@V>1;IYeCkse^G)(t|R{UL;L5P57uhC^)<2@PJ7yE%lUsO6;@$N zsk~Qqwpt>RQ{ZfpP$HW;-x0Dk_SGhv zy&>m|gpRF*W~Uq#X&5of+p(KjzVOFw9^bvqqAT(&U`VIN$DFA;@*C<<$VPMhL4H3u zx8N*PPpP;bdy}-XA~vu=4tGo31opZlwMzYYdnCBWv@NOvxk|qpyS?gz>!}Jk2Iwm5 zDgvP8f59~t>I5Oi5AG5DXw>M!F-Jl2{5J5~0Ep`9Fc4HjGuXuwzw)O%#pJ)1-99!- ztuaZ3-<{%J*%+gC(o~s_1M<``L+k~+N#7g=^Pm0jJjAay0(d><{)Qus9=7~2V(y4S z!6q(rO0{21*IE6co?&!2Y4qC^XV>2HN`Qqc-(7|XT`Gg)G#H1|iC3Wp`QC!W&i9v4 z_}os_r3YTFi}yFpf+7vY`Bv|TwgBWo<}Dys^D%SC=brdb{#2iyXx)WI0cdN=#c!HD z*sz0U|0{^=8nBKO5n}CAPmqA*#vLG6BVIK`2I_Pi4Yd!j(WM8T>r_{#hrD37%rIec z7n|8cja0W$6M`Jlaf6<>aK06O?{Us9Gq-mkFN!Q$-U(gplnVmZa|kj5I4=e1gjtJ{&Q@;TCY1f{fJl6ch722pssn1cK685%)HAQ zFip`Z^osuYGZ$T1O;5SRHz=j-^|*?M4!D{0_fHr544^b1>2mrD)zU`djor zZ)?p$RDbvCrCa9%)~P3D6?d{P&EP{?3LUK~G{tSY*UIeOfkNDch=9Ha=ptuGE40C_ z-Ju@acrj8P(VCYhbOmwzFs?4kFDZw6#5z=*{{oJ4%7I1$Sq(94{D{@t2R3=&9K&ba z6sLwFi+|L1g4(xwUH=z-C%Yt+a)Ql^y*UH*e)2E0HD(Xh>iiJkN|P3blS!)n&&#w7s3%pJ zuG}z%|2i=BvNcElFBwBK?3#(J)=PkkP2qc(sD_4p>D>^ySjER#tSg2#AAZBlH*2Oi zR!J46iOhW3m7SBDAxg~M2VD6lVCLfNOC#zxx-nU9z0vBqDQA(^+mkWu@9@8DevI$PlU&^Bhcz1 ztoYgWP+mB`GG7CFDb5#l_TJ=w6^egiA86fNdQ3Gnug*aM&T$!84gWvuAAmuc{hBUF zEd1L)>0Z$_VM#N{*7MqFnka|6KAkm_>pM#5`8xD^vhZ?&{`f+t*vsPw5gHr~gMM_b z<@5yS?o#cLRQ0wsF-}1%q?=?d0$G$2%HQ zWHqjh$X#}e`DET78SmgNVnG&fw#-j-G2oOc9EFO-h&r6z5vcf!BZYaoGXkFD$J$(Ql=SV+xe=O^9LVV=|4v=pR1&tXN&sINJPngkaqjOQ3dGt!*?hZH zwj_38_wqTxKwFhvU5W~;$pIJHE$LiT_VVhrC+Yu}3$WP6{etuyM1~5pj&z*>^QNw5 zfy+w{6<)$hgyFo1pRQkI5?A`gvQ_YB@k~(%AZazvJ!nK##AT23x@)vc4{=C9wo)0kDlKRI*AS=P0j@2}iP%*S*$b_lsxtycWy)z8%%7qw*@=27GzF=Z&TTo@ z+xz7ojmwTIC)iXORU7@jyHq_8J6upVN-CmDUTgWnyppH1Ag{XP_@pyQMX#%a@$c(K z=kwO(rfTSOG^*JSEOo;rKy;_`EwJx%JX+8Al$Aq4I5B+eChX zZj&V*V;yEE88^Hi)W3u1OKbTMHTHpXR_G?1319ejHdwh0FZEm-kn?y~_ir9-Sbm@mf50_ReneU!sh-O3sjExrvWS zndHV|{*3gcYQ@(#gzQ`61GLCx#A|$Fe)AGhd0<-Rg-ZNU^M5YQXXG@C?bJl-AeDr|+j+3fSMV&=&RETRqOQ2i zmzp6U$AQ{c^9^@MDj#KcB0`icO=S`CVN;HS_^oU!i+}HxE9o4u+hA834E$bX8~rrz zY^yP3Y-;_s&Pu#~QdsxNN3flwa|h2I89JI@xq z+av+7zzK<_n{J9n1$2oJS?XCT+}~t$O$RAv)uKvB1gD*TPQ*AqVQ*NW@p&u1n=72z z`?p-f=OmZ~#O>VtkVqF)`k6A>+L0G+euc7W5^uo+droh_Ol*)Bfw#ud&8a=EY5x`y z8T!Ay{QnBGKW_2SXwkh}J8wq?e;;XTw)ZN!vrkNMqs*Lu_mu1Yx7+lW#0|l(W!FS_ z(st+9?S^s}VmTuVcbDK)^Phk#=~TjA{db&p;oYqiSaPSeu1H-hObxIJnH0S~EfEIZ zf-2}EgOgb;$5o_rAky=?WXrm&u4R8Hg?#NB0y%)`UhZ~P{fDkjDc$0~wy~55;qD%W zZ47z5_EEa{2WT=6*_B??=7cD9tGUN47h8CvPbFvScVE*~9SG`WxlSxzVYpsVwPM?X zdg__Wo3=AvSJSQtpPD%6sw@W)&U@qN>-Q>TtA+5HETHklFB8&Nnr8dD1e_Q?{bMnO|tKtsZ;^b)W6Gz{7$74ItVl^>~9~moMG}E}k-9!($VV|N> zdEtR753_+)G@4VN0>}Vm^$k`XfaBCv44%9YOS=~M-Ttj8>D-#s15@DTPz0r-<+74y z2^qz{TNW-6`I8>i&b9IicAN=t^!9m{x&03NZqQ-)lkBHwv|;~*10UoR?E=%@f@SOI zJnw(`&jD)*U3Mt0j;CqiR7u~G+{m<6r^rRW{y!)Eo}4*aS7`>^*H>j!h^V+j<;M66 zx)zTnbk4iGR2jk7v@T_*!5)YjMze`8s<%4=tx;03%f#zGFA7pGaX%%CS)B!!>*=SF-K+=M6vTT-pkqR6G4XP+nYkS7L&nMH|lNl@j8=LD^Hv zg*#RJ3hQPZ%V_Wx05E!Z)I&fCV)-U$d{zd zds_(p)ToHIl{3{Q>D%JQp3-VIR+SHn6-S5*SEDaFDUISpi+v!P-04o zbTm<<~&b6btOP*0M9Yb06DJidJ1fmsLbuMLtj`>#eAqwIo%@xFUU;<_$v{yx#mdq1 zOeE$nlV|PDCvSknPLsEOTWbeXC=J>EbY8aztbfpMt>s-9@kFma-%i*V#vL(Bj=k2! zLdDf@x(~7)Cw!%@)kBlSNT(Ra0vtzI0p_jtm;Y7nEo0jpX4z0UHXqf{+;_OHIDcXM zvrp`bQ@!*Yhw=F<>-X=r+t~Ji?u)(02ddbH7 zbFFVIsv2&jJ~dKULw~#`pcZ!mx807|iv1$ai69t$&yaHf$a}1-USZdHCiFq$Vz!v& z6FV<#hbPEgNge;Y=A5Jx@-M`>4g$uC$y7JGV|RdpxPP@z7(6So_1P&JRaDJoHS z>CWb5A>gt%0vvyhGaQ-ubMIb4H&V`R#_vXMhgsXgJT|WY5E~3?LcBPtI_m9#=xcfK z`~(~2Wnbhub>$DT2C=*NNm@HUbzy7m>x0GOdg4jMBWZ9Ff8UdE5rr8LM?e! z+3stM$2X4hYY#GjXb;r7d)}Sv_&6nnj3n?IN;1!%v_WH~{oR8w!W8!KK^9r&!&1>je~2V9IXb`5F{>5xjq};bZ&ny z3ri;hiy^16xhR!k=BS$-)}1_~H-vr?3+7e_p6}#02g&Ox^lZaypM37|PXERY@QN4I zhY-0^@y~X9dYEiuhECK zyWOSOUB&s16QmK%h(|w1#HX1Ka;NvrMGE1=vXlJx8gKB78tv!4_7K_49`Q^IXgm(i z0|q+Z+5D9SbA|oFsfN&(>H;n$cAJp5$ByK)^CP@vJx~JZ@68K^mF?y&6^)#qaH!Ty z5&&+1_fW&X*WCuF3%gZeI}`f`vHsMRz5R^FMPm)DD+b^LboVv)rk*!WlP((#WKo&Xz6K< zWDDb=W!+h=`N{TMStqHtok%mMt#3u`-U!6321u5LV?*rAYRC7a@-Y%T4flGtlM%L_ zGI<*B0gY<-gS;Q`Q=Q~Oe{3XR?|OGC177gVZrl-j#m{MJd(Qh#yNiC(>0g^l*%nWo ztyg)c^N1XM5iLpyR)4pfqcwRzv4+#T$OdC?z^br2(m7~W*T3#?yv05$$fj;RmEL_p z=gax7$nc9IPEr1HAus+;K;{#|<#8;^rGC(TAA7=|O1?RDd6e#oBFKJ_|+qL3pEv^sdY1-iw+56~ z?&LS(>kGss9>eMqj?^Z<5nVNo^r7L2PCkR3<40jL$%yY(ZlV=;s$Sj4q8Ovj^rN`} z65HmM;|IM#M*d<%BV<0?6;H9`3dxWCoo|Y-h7J1y+f7gnUo4_PrHUVr2_LZmFz2AB)>at*dI^c)XqS zsBg`YYcs2nA9AhGmkSp14e9BhEV09<}uTB!4N756Yy50p#Mr*4=1y*Gt)=KWqhK zOG?izYyi^?U9~b`=&j@#$@+1H5Gn93@rZl^O6UeUx$8U!K^jG8LpBc}^PCZ+3j6SV z89Oq}wbgP1<1=oQQ4OKQKIr_(OeRj&5#b%g?VNJjHl*_DhS~nHo};W0r&{Z$i9~|l zb30A(_wh*t#O`4s#bbA2F~`I5PSL?%y8l@=3(}FrhFbbD&$W?k;s;aa&941U*bBfz zd4Oi}`PK1q>z(#fBcdUcS;ru3Zb|)h-ZV6MV3> z23#8v?r(_Q+t?BR7itbl^QoXaooc^w3TKK>JHI++<4AS@B`NZRu<#zJ^8`y;?|5<0 z%i)_UZ5jvv2z~)8WT-x>2^H3Kw5$Ik>D-Lo-*WHm6nVc+j{SWkIzVFN;(IGSAGrzM zG7UPc3^A}g<7}s0Yob15Cv9D&7Sphen`-3miI+4fO!lvyiS6T!XtN*QjhN@%6v#N* zLT~lQds!VGK6rx^myw8O65$$TMnQ-#AOstdiU8kuYNx&S@Q5>s{zR>N_$U27Tx7~e zcf+N6=S2vQd^AfTb5ty`Mk^bgzy_k;lUQj^T&-$VyZMM3aZ{mafXu}g z>gh!r(XsNU?j}E0Sg1=o&JXj3Hi%7s#^vG`mH~XztK`#9CE6*$#YpEPDNfCSk!pb+ z*(FI4={V5Vma{JXl>Z?f?fop#ch1$vcw8=qOw8g z*qGrA^cli=_`kB6Z6U1R>*t|07S+Tb8p<_Mt)3mD;?e<`fBfDZ=P%XG;*l~b7scUU zxZCjrE2u#UE~YLNEYdsZMVbx~27NtV1@#$+2#rEOwT37t5j5vBo?TB>IpY1j@9140 zFe9H1FHSMsyu9jXDJC%VBFJXS&1m~C1$m=P3yrQCKGK}O=AV|AeP{o=8~P!0y}Yq2 zXm_c8iI-~sWciD^&CTr3QWLh~5L%1h{TRAKe#jP1{-eX#BFc6#`V}tH)^}1;8XuZ5 zw&~pVMi%x47?~;U0T(xu(9VQN7i?~eIG1g_Q?X@ZZlg)4$9Wv@X6;4`H09%C$y(uGMdgkRn2up@cMMvI=TsJ?O92Q@?U@I9M+lOB|GZo{r)$w=kr{MF! zBsW4N!{?-wz8v4&czD}yHqsj8Pxh9J(f}vXkvaD+FPrmd=RdsW|E(WR&VBp8SH(WJ znrn!3qeORdH?pws3w54lusc#8QqiVsE$SnPklN|_>=<-b0H@4&-E?ykk3+s7fgG!D z5|sm%jn3OrmHyT+s-<~_1*t}Mp3U9$S+U`Hil)wE-dXKUE>~Rqn{AF7l=}|$s2qIb z1EYS3uWgbVA)pW=JF!4fN!tU62cc%bl&>8%f&8671h#lYa-xByqH|gf@uZh^12u7zKlik$qM1l%S7BBF98$ z`O!8hSy*)8Py|r~*k&iQBw{5b_o0Z!Dgqb>{ND+I@ma-wEBlG0Rp~iY_I( znE~jN;oDUAynoF0Gm$^9<`?7q*w{;c2`5bnggWbf`?GygX?`;JHg7BM72m#7gKV=z z0nY=&qXsYgu3wY$9Zi1}o`c|HuO`Tz=N;i=<77>T4d2zQZm&&Nx8R{6P-V|XX^STy z@gCfIEPJJ_SQLcdAxt#7r9d$7>8svvcU3++_Al>PwkMRM) z;#c&=>m~NCg@?kL5dEWLnX-P^k;7{rcKtr3U=tfRa?0~`5E`8WBcEXD>g)$iqYhhV zDf*jh1fI}kYL3AVkuEB1r4p;vz#*)UQ8m!=rb^>qiBO{*PIKbguBY6Hy>VRmz6u$fo5LP32Jnk@tMdzAVLW@_{E z%lnd9rH3FNL;9QgaS%s;r6ToK@I6sqss|ca{%p6kUwRX2a6}g70Geet2nTLecHT?Y zcFZMx%Z2}QDJ61$_g#NBes|1q1?D1D@zA-y(to#j4FWpf{-@&YCP$r8hoHYywRf|y z0c2G`ab7v|zzBb^o;ya4f+m`&*H3TW)z9_VawNi5{LSjmXhaMLYi0P&F3i-BxmLz^ zW>c&#>eg}=*q>3)F*ROW*e=p6Bj7y5g1J(0S+|p)0{Qe)YFfcipSk?;3vD`A%fYwj z_P%TU4Gf6r$Ocl&7pRxg2(rfK*bQ*Z=MY~KhtFv{_xd_j5Zn1DTs-{?t?~`v{@cY~ zMSCC1k952b+nj9v1)5g4#yj#=o`Xfjc_JUk*Q;GRU5KkeNKmsRsj!3P&&N4TaCaE? zKG(rFvil@?j(ghTooS>Xwtir{)iKZ3rm{E;8>`A|^&sPEYsrX-s!iZmRlVn$1+X!% zg-Tkrm!eRGR&`#up_a}2uKl{OP7^bU20uORSk~!~y1S-@DBGuRm57ZB$C{2TEsm|1 zgU<2T#jWILC)_At+VM8rt$Kv|Z!czAVt(aB`nQ!m57o*t;X$CCx};%Big;<6*54Sa znJvfeS$1cziI?b3HS(T7tNoA$K#>Of8^;=Qj@ta?9xVpb-s5&j;6lH;^K6u*D{n2K zna1jxt0mwqu|b;J_hv#zt%tsi!_U@1?@W6kmwN7?x`ogmO~x)O%eY2%E+ImaTELKTw%8ES5uo%<(5<|6^yAT4u+ zY=uH#sSg2jKC8XK%dZq2*N`18yq^VMc3RW1Xpa`&u&}1twz(fJy9%EYZ#JjddwYYW zacphQLW-~dXg#||YObu}Z1d_0<-OS~HP#beuCdyJO!q2{=DwNwVwxtCVfzbG3ZVN& zo5yklLZZ7q5CM@!qgBtb(A>sM2kWc1%tCX>mRaq56I@<8bCB3)#ol z$Ayeq51A?Uv1HFp2qFC>O-85$TXWWjoUWJ3uXfH!HTpa_N!%Tkf& zWKg`mVq>{GDPnKcrq7um{4~aS2P+?pRMsW#{*!zs%HK;y|N8@nv7{Et(tjQyNshjO z%d;=OLwX0TavJFo2|476Sg|k4q7!5mZt4rl(m9UVh9mZanjB+>?OVSRMIh=~;ArH$ zxFEgB{>e@8^6cdZZ3~A__#ptGWM$kPb3K@DMf05c(%uurysl2HB~7?Gul=lSE@rtAD0Vc6^E%J`W*%z+pxcB zj#i4fO~L#61ghSw_WHi$I=fuOAs3bMc_z7nl-?F%0O6H;tTB!rTG+D*(4&xZ0Qf!z zTI{Rlo84noW>zNP!Ly*SQbDc`y)!hhyvH5m?b$9~^V3$Ok92|?v0z2QKVTa!LWr-n z!N0S4+ry;t>o3kN!b(#irjbQqM(xk|iHl9_*-seYzi9sifDBp#fci4}D z9d}D|EHs1fh*r#TsOu4(*D1wuY%$tf3-m(~%p}gSGU$))Q47s>YgSJ9|t{&2$pa#n#XOubpr7kB-wuVkPhdI*N5-t z`E6KV<5a5u@rSFq8!{h~sEaB)YkGZuyZ+WG%8Xdv@o;0kGo#|n^fLMR8Fs$M8?xaP zyynH8zy6mM9b0&BbgPd3Eig@T_QXW840c4}lLUrld?+VpNp-v;M3)5(N37{&jTWF1 z`AMTAl6gJp_WP`w^0lzDYv-xfv$rqUCck-w)Nam+$?;0m(87E#)+b%yL0kC;5zF;b z6fQnE{1#6q&aty%X5leZVBbTCgoQ3LEKOWr1e$9RM2O{!&h>xRwB25SA0=8IF6dCQUX)D3iiP0{^&=NSuI&UgJ**AIp3S3!%Xr0ybK zKZB*wWnpl=Ma}yFbi*+z#O!;FwKGthxhXu}K?A6e&b(IUk~KH4)*=P1Kx3nX1;r!K z=F`J!(B4RYB~sWsAHb-8q9*5=>SM;IKOGu4Rh)e9gYJOPw{v z3t|h9gO35hch)q_Q*pwnyQJ^NQG^j>OCpfAD*>l1M7g{HRve09-$V-fS^ z#TPdXCVL-nHC)*#P4|gQ0#-b_pP2HRqDkH-prF47woeqRnma%4bnZk8RV+(*{S;Vj z5U<&e!Y^Q-ojCTkoDaHIujD0=!0Xdd{3HOBHA@6lG-?y+lA2C#h8UG4D|zi`z-7d= z{gZ<8^oo~gh0Ex*OPpsoW~OJ#i=GltmF=7us%;p%sXWMv%J`@_-+A01mN&&aOH}Yd zXC|EtyhAbz#e#2js+kO%80d!bPUsa?q3YYk8OUGrMkVLLLSNc(D9YeiD~GIvzWU(8 zx$*qamASDO<@~o!o8#2Q%-4Mi{y!IBXsP#{+2)8<3exK+*-$TS$KSOi>jI${yH#Rl z0K$Actu)@=br?Fh3Op?gP#3b2M-LPCFQP+^M+naveq`A&`UxKu{th3a*za!_3i8E| z#QhDaz;JHQTAjaTq$`hcdCxI7KEna#;BmbOhXDlW}25@0JhdU%^w!Mbra z%j0R2Zn&u7=P*e2_Nxf%sWD(sY@X)~Kf2i~moQ0g41}$I4F5 zTj{zBo;U=NkAq!=Qt?f9~o@ z7E6--_ilSwoV0VyifFSciLXMeb{KP`Odt4T6+ za7md_H#l${A7jkV+1Ocfn@+*^2_*aaHDlPiXX=fi5Uldb-tZQ%kvZDG?S|s2#QMTY z(mZ|vJ$Q_L6nRh1F{4h$Xgo|36=I0F(Y;$7gVzgyj-4bvWZb(gNEHzWFrn_qFHDb0 z_-0bjzLjJA%J-1DxrZ0(QB%OOe6|aqCs^yx)pE4JNZjX37><8(v>e9EJe#lA(pz`Y z`PA$LJEi%v052s_K6T0bDdOrWlxmdn;1O&LRbX`WJcNerQRlM!naLj*!f#LaFQ|*tw?$DD?FG%x#d!S zllt3MG?bEwJn8-AP-x5OEb~L@O}SB$5Mn-(4L%%*Ze{ff1n|!n`&=!t4~+ps%4s=_ zQ)m8Ap+4VIzA&}zxoYJfCBhT2Z}xoq@_{3O=Fgn*rvXr@RQD`Nknw4nkEV@3tM*zx zJ92qLTdU%#w%H2Bo?#{|L4Q1vAv9LbfTWIgKwI{Uk=%*IF>AM$$=2~-#%mQq6_nWh z#Dnl$!2nUjx8~0bn@O9bzzT&jkNG!#Sea!3^|;|;8)1H5`eQZmiOo0rT2#btGX{)f zYN0ZXX{bA0r|=6IeL9$X(fq-s4DQ5|t4Uz(wYVqDgA2byN)0?8GL*dI=))M^y0~)F z@1YBa%j!$Cu^>PjT77o`sS_dho_wpG7vvLTxkv;;l z@Sq9)Afd59<*alz{9Njk%(3T(vTGA(uED@OR%kQk%}Zx^4QMscg_Yy6Dci*;_!JwG zU*8EE%NW3&)s5S}%p2lUE=$e=jGZ36K0=r;uu;_;*m|UU(d*?o8k_gF zBwk)C`H?)x*~?e=rvCwCT<{O4@FLb>>R;b^r4aCn^7v3WY;-sBu4qO6YZiL*=X#Pf z7e}z*-ooeUB|1s#w^HzJaAn>Q(X{HjGBr9as5PMttm))6S%SsSv!PtY zg&aG6^TxE5x9%K$VayF5?inq_@Ne4*tz^tsonDi@dMrrPvbfVSI-Z1p4HZY;a43FF zsgZl970*T}PO>+}CwveGdwoa}Kko{))9@-U=-UUUN>v0D^J^vvT-gn>{+&BrsN-Mq z`l*H4x4S~VEh`twyJm0JLVagSUv!2APAPJ3#JsOWEbd0)9kEvBe}a;qA&1Wa7I~sd zjv@ql8Tbk554iEz{-z&R!ylYBJ_*>wy>@a!v;;@Z9amEGHauGG@AhZPq9^>(S7;aiISd)TMd`LG$>FDeTQ=NwTQ)r#hx)>U#BCYJuoQwS@R7AJk1@-7{Z-}Gh1no7IWX~sRRmivU zW%47hs^K|@1a%|hi$~}gHgyz_A|GYr-MzR%*Mncf+TCv<=} zSlT54Sdc!ng$PhWX{=7Xw-Z0W+pCmcIm z{Jka@I$r-o3_e)N!N`9`^*qlslGJ3??ru=HfZ^fcSt;vJB zJ(){5WB(a+^1RvJ7hTO%OjCLhUI z8x|qoUc<)CZmO zQ5m3ru0(e$NoYi<5@}b?4W~@-Tlm>^wxz`b#JO(|0t?+-)w-Q%Ff;l$Y(&k;vuA@7A zd^q#|D}kxx-KZp}%)wK}d>l16s%1j8+D5!|-)MVc?wp0S7%ocSUBHo#H^E;SX?)_{ z2t8q1pJ9v3o$^2^nFPw4SE-HRW*Sc}4U`J&Uj~cp>#NI$MKLCQdXFEei9GynVfBIb z##`L=NK`_ILzLS29VnRM=jpW-Ew{ZyazOvBEOVXLSJJi?ii!@aKjCE@J7jPA$^t4X z&J*LdM?ThGe_DSf8q+SkTB+D^V2f1=afM~^%wGAyaQ{|z>2Wzf9SeW3$4JptUH1($ z*DA}Ub*g8UC-ki8=JbyaE~u#%?7wm-yoGdKe{b3*O?kGU_L0b0m0c{*M?R5d_ZVlH zr7hVjRp7hGr{K8{pJ7A(M|1RO0BvT`=`U9cZ-f_MctPfJ4yhFZAbfl(CmQ2PPacRXR%vu+J_&K+9K2TQtQlR%H0e< zBnPaVF^=x3Umg4{paYl)Ea%;Ge!(&fsR#%8@)6=NKrluq>h8Wdyo@p2#X{V>3W{eb z4-f<-TuL+<@GIq0S&vzDs6LY$MbGcKRwNh?>F@MZ8fyHi4nJwOjlCgzRlKp89H%HAR2I5mZ7>%lW<*GNMpE{n}kxb*J$*bohC4iZHY0rE| zSkilY{~UW}_kT3dvq$p{;DERL&%vIcwhVA&H zj#}B8qrF_ER2e9j_# z81J?1TD)K7jmK19UP~y^Kehf!Uf4X(@(XeO)YOF5tHB0+z19OJVg|$H&dFFJn^=5S*lyMas&fC?zAc^Wu;0weCll z#h(-s zHbn&RBW$&piw%oqS((@fDA4&F@$tmFONNI*rAOCW9*R~3w8!vOz#nbU^a~yf%x-c_ zaW^`fjLit6T&mG<^Dbn2!+AOVu_?YfKozDU+4EN|%Lb)8Vzzm|Sp&!n63%yt|Az{Q z$bp#acno1Wm)17u=Wx_NXUetJ2izE7V~aWm6q=9c8w4_GaIW=?ud+HnqKj6n9tBEl zz1Aq46Y$zrT{~E$iB2g^PF13(JiIay>;7jA!u1h-N+w-D{kalGQ4+P8%9%WVP*aIG zRY?;;9h0DI(#l%&Pqdi%M(nv`5kJS*EdGP1VuZj?Cmv{Vh75y6IrDMwKYi3r`I?5Wdk>Iqwt6S|xT@mLcxKMAzqQ@<8S;=m*N^n_Z5EA(HP|^X*%q zhdb4+05P=+wP& zmf8YeWvkazE{bPT80NeovwG^+Ti*zpH8O&kDA%p~%27NC$z?})|;SKem{AIrVZvIEx<$Z_`wx=(#(sJzn% z^LER{znQ5}-s5)tnw-V!kAS*x*xCa~(#tdE-V2cXzHP4b=X0;OUs}2|$W~ARZ_3_z zt@bf*1$EaVyCV*`HMBP9A+yg;ruNUJ)F3Yfa{4Pml!p)r(%#T!JN{{GueYa*g+BMr zLi)D#ONe7Uy9k#RIA$Prv%y7hfq{9fHG4(4?(vM!RH)nkquaw+xmP+gIeV=0nbV5` zHfM^1-l*SqN&pmrT0EWmTntM+c%%Bq8tI`2Q-xXh^`y|Gb@CvDtKkNR!r;$WG_DgS zNpFS-xZFLxz|xVS;6%pw)#?~M%WpmDN#(x<@A+ZvG%IWqqIhk00xNlt3R~=JVb1_? z>Kn>ttdpvtO%_~F)TJQoLe+~oCjPo2MYqNX+Q*Ng1A#vkZHboB1>QxdO_f*PEeZ0y zh%jCY)tc~v^`h$o{s{LvNQPeOrWr$jbH=K)DFj){z~H@Bq~=d3I)0~eLww0)5X;3V zefll*B1#%FRX`8L{^5Ht8*QgGukr4=-Ec>fm1$^~{$s4;i8Q{EUzTN!VLyb(eY3;VKKikYbChEaJRx1W2*X<9n~d4VkAqasDDQ*? za{ZLDGp+?^E-y5G4aUnv?>Ud0tWJKqlWEkGxKdf?EScn`6H|mterIQ&pufAkF|v-2 zXPyeFgv^Vw0Se?xCJ>*s$p@0~M(r@SFl$~20#xA|$Hv~?E35VPdpIvFHac@Q`_b06$(#dBvs~qHzTNQ<`ty|ML#fS()DCW7S}iJ5XFqW zT|OON|B+m%OV1vD^C(y*OK{BR4X=ek_Hp(QEnf|3F^2#5n0$9KP4E=OqvcLJYuvxg zean0$2jaL3dHl5bpq8Kzu`rDDF;;DilVQKgLTHPA_tc%9^0(J`K4$P)CE(Bpb!p&} zRuqKP7v|S#<*cQFzf$^s__d$YwjKTi1vVv-ji_rgurt+R{Kr1Li;)_H>hB?rs%3(N z#@gpa$FH>Je+zAK9vRcE8U7j*3Wzk3Xy^+ijDTqF-beJtsqZ{!Jibc|rjlf8zb2%IAN@vG z`+;E$6uv6=+P}cQu?_D>V56FS1p}U9+y`Mh)Q3K_bF#C0MLsR_yOAeMj2EzGX4|y9 zW!mUa;cp7Zv%3ra^R8bYj%#C<*HonI#{hNAdSA(F%~bczLlmW8EXX+U0)}!ayYj!E zTsLWbrSX|KaRJ(pAVa7-Z#$#u9;DB(@s!Wsjc)muJ@dZUZQ}+opk<&#o$S!E%!`9; zWq_f~IKUm{57fH60Hl+WP$i}zfusAs@u^=7B^rf?L*~pQlF>5d#*0X=W<1hs{fy;C zWtB(~Oq(VfDQXnwXW9gt8$=mJA4NR99=iv4K@qFSG4=Wg;|B8COk;YmqSn<+JfUVP zlD5=1K8^VqhJ0geJFw!#I^Uj0p1veKM6dc`-bDVW*U&1>)8Mot-=wBG^PTm_yLC*m zx%*O~-_mX)8@t>e7n0=_IOV7d01<|otxVd;f_ePFhp%n_N-q>pa~Sq0SpSbB43=k? zt61S&L{?kPw+(LFu7|d3eeI;)Auw_)2l~Q*cUpp7lRS=Cy5I@)3c!9bmF$0&c`7Ln z5Y5+kpQTKc1c2NNfncRI8^pIP(v?UC-La*#zttr_%;a~`WQVGIP{W`gzoqui6Dvi> zDXpp3Oe-X+$E|oTj5%=u&XrD@iY=<#+^VkrA>O6d5K$a->~<2h(&zH)oE|0G!sxr&wbXWM^w*UO1*W$CGF{Z5 z%=VA;7Wmt+2>C?i#56r)uTLNUvNF^}YE?5aIq;!enh8Qb^sVj6C6l&PTiX0KJYKLP za_!IOE2j;viVoUNi4Dr@LWo1#3kRrYOI98n)S73P@pq8-A-+LOUKKY2H5z`tF$^ynJ_PI`J66`H9Z43!jOp=wi!PU;6 ziU~9a5jqr^RiOXLr;NK(2Mf!7N3(<{-?~%qx|llhB_ei5zU1vbDE5_UV+6rm8LM%*T|XqYw*pCjp}*d6$%m6{rq5KOIc>`0 z51OOeuh>37(;Q3?MaPo14P~`$d3O``_3ZGWeVemv10)oQ)^PnUR|A`s;-0hZ5W6mq zAkeC;JozrKdZ_g8yGx^G(X)a1N^}1(zU?wyM2LSagym{RD7n>YV~Z|V&>fNW%T#2> z@8`sydN2+z?Yg8<{C;NZm|w-QOUl}zhQqUVDj}~U@|0+Zl^bgFj;P|HCOn>S2e%J- z&~RS-C>gXR(gDP3EZQALtP4NNiE!3ECNnM-h10k!Y}QWbM2}m&=(7TMN74bm9$*RL z9Cx^k^wmD7o1ku*&33IP{Cclu#ASaUuU{ zITOx1VYb;~QmeeaHu8n9g{mu!lHxBb%)3l{WNML0`I^rcx4)g5v;5_4&~zfvWTGEAA2f%CIQ48H_Au5Flc*5|l=-eWZQx+wa;xSNwkS?faPan(2Jp z7th4nT?2*omBW>;H9rhSXX8g6v??I*y4!Bh8q^KO@|QU{+f2YE%M!nT)3tM9E6m_D z%uNW7ck(36J$P}Vi}g7dzKQb}s~)!Ww%uKv>eG>PJiq!}jbm=Sbl&?X&E)Rtr5Y2I z^Ns-5gLnPfS`q?mUv$`C+)mr+h(Ag;piQs(X%jCD&F&FGTQa8{?2R$&k`z12{0*F7BTDv*qfi0S%!rm)|D^1 z>fH?b2yK{mUDKRMUaRD9l`Uy9gO`l87H=`@{fqDLlGQy9POQw-`yoi^tya5+1J_WV zZ<)$>|J7V3osvrL^8xXC54{+(KC&9#|Fqt_{iG^V@RjzTdEV{MAj~Rd}#YSv$Y# z1Al81>*F#xhu^7v7oK+8OO8J@`~O^k%4u2@0`27;kozGy`}1(Ln9CKq84I%;;+xKy zSC%?DL)Y>+Cx24VSh{gVrV>*-98s}EA*eC*;dESt#tF9;of{^y}8BgO(bd= zs;CWbTE#!b$6jpN&+c(Wv(cPB4ZJ}-C;NkYmLDx=x&m{47#OZdY1Fuwn zw+4PMsPdpDQh0Bis=A02a_MS#{I+;(%ivbftsP0&nPa1F6I;5a+)Z{x?$Em%>`H&_ z-KJtG$YP1|f3@miDW8oQLcuqd!%(7sH^1Jy^StXov+gb4B&9(@zFaIrW{*F-Xmsi5 zAx82~^X2Qqub%+f57+g{F#TQBQeaLwgw^3vqayneLx_x2w%Xm_7Ggs+AEZ-)bal^` zHN)JGK>)lHE|bdgq5VvE;hPx-M;nc`DEG9b=kcj;GIiZ1>Ti7mxhv<(2hC$6gc`>Z z6mHLCT@R;5*bK>J=QcgDtp2ieRM#2Vw;Q>sBf2EqT@~=MU^m>&ovyHz6~DU^);-m` zB=h0<%!VXzSnjg~C{xqHzrBS149#RsFz+{3p%kw3LO>#$*Q@-(UhJ@kM4S;4>-Mk~ zG361Ue@ePMSHEA4Eieh@v*=-B=6D+sNc`wq^MUUsn+KJI6a7)Ybv7rYju4It(owKdC(Vd);rcYfTv~%_Ds((s zW>5jI3EotiJ1=JNDg5QSac1jF_drV-2AR`bEjTX}>oi#Z;e7(8BGKQmY2(F^;gxvk?zU!k*e4WRb9M;6|a(6=qrqmzWef82Y- zP(}6|+C9b&4;U%5i&W~*WE1WKpA)CjmKl1xkuWn3>!zKPAp(Dsg|@DIVrKln>*h-8 zi@UH_NJ`#sART|bz?MCb?s}Z}mkiw!kWE~csTj@J=;g-RZyF@CJ?u%nkOWHcKwj&y zT((j`<1D`VtdHL~X#5@erq#cVXNZ3zZ}SXGZYZ{2bY5t8F*s*QB4NBHQS^%Ccy!yp z)kPHZbGPcZV?MG)^fqEsJ~VbPf)$KsW_5+G+dDJu&au_uIWQ~v;%bbqG4;x-Eg-$X ziv?YjY;;H3vRa$?oFF`DYEn}iyj%Aq9Ou_69#?&pZW-q7AB4APOL&_UzW_o@{hybK6gvi!ZYsALhBF>fH4# zn*Ar?8u->wgyRF$7tri#lkSxw<<0adllA_~quN{(FNM-OP{Sr+V(EYh#Q+Co8Y86J z&erl^niIi0@%2WKitgI=q8+ZPed{7cj)unyTO?ms&s-fA!%gkEOPf(XWas94;eBT4 zBOdMVANdA28)gn??_CvP8VG@N|8?yUx0RF#y(N57?VlgLQKj%*pDJ3)SGXN~>3CJs z@s7;4rlrhfkDxjZuj6x7RBewMD)p=#-Aa6OCzo@&I8STi6)jiW71^?QY@**eMo40e zlsOQ%`Qn%bm5LzUyP5jVvOEUcaCO*3L2*Llu#lBJRcju}vn9Uqn!3MTzGyeU()qZ< z#M56Ch4Q@lXSnb7R=6CzqLu%H%>4#M7Pf+I?<}R?M<;&Vuw`}Pd@6E!+>HPDQwhi= zPMgzFtC!(hca@5sg3}pe+E*w%hgEq3D3Z~(*>vI@TO!2wVEMhDl6w<-&2uLu(8p~N zTg;eSvhS>MbO2k0iNBKVhlP5p^4G2I?>xV0op?oY@V2j({`D^H|Qa)EM_$g+#)N)s~fJP=NVm3mvp^Sv&abcXmjA&TTHXAuQX zN;COP@!@n*VMKdEby8?VMEV9~8_z32J3{5?Hp=x;E{?=)X1uj8Wz@?a?oRzdDDFlY zVo?dAxy!q##@a8HVwQvSeBy1m*S{^MQZ}5QGT3HJmoLwEmmTB(neZX=f-`?EY&AKC z7cTc67unw6yCy1*hg{$*>ZIK7IVUuI?FUA2Ia^QupmZkA+-#@r7Gt_)PGnSv-@6j5 zwKf!;I%mN~A_9JLh9&1XaJ!M?WjAmQAqZCz!sUnof6IJgL0l%Yh+Hz>&$N?ylzqDn zD!a5yuS@Y0+VXCPZNP6bC`jf;jd6I~nm0T=gxcc{r)Y#s5nO)KJ9*n%LwzkWj!R1z zkw-ikv5aH{%vHjlN>{5?NtVbW|ZjPdi>C8@#m4jkkl+=^g@y7iG2OM1lT}Zc>PF3~O*+lCTC~(& zHEPBV5_C{S)K;@Cs%GpJB&wu#?GeNdB7%sJNb=2Uy@5Z_Pkdk537}DEPZx6^7Z*-vR;EKw4DX|aua$*L*A7S zF;fO@gtqH^@=lypf46gTHDwfc#dHOmKk~BaYM}=KZD_h)sA*X57Mi#AdzR1UvgXGCpe73B`nzdfy=$nC=aX+G75Sp6M3&l~w+Q49SYABVQMN z(DTe{ZdWD#5ZLXTMUAMr$LNJH*uO;KQNcHVC-PY+&5;!{2&b`Ht8dsBs(O0-ZWOhy z2;(G75X=JX6~{d>)D*<+v!IBPIw7o^(g@b(AEO# z_wk2t?E|T}a1Zk$&Mm%T97vP(f^P})K> zcAm23Fy0}uqLRgfL&CC3&T>ubVE)kLGT!x|Exi?E29YuyXyB-HMi*Y(Eim4|U}&d0 z(X~e24kxEJt0t`+Tkn(m29~68rDk*??<>l#UAbE?4{hX%yDgo~j0+Z~d{9YWK<^6Z z5gmEtVA@vZz~DG{7s1%=c|+oYhONk|fzgSBj8?H1Ip8`C<+5HtdGE2*6#&k;U!8V( ziooNUvvGD{&*5g-IMbW=OK$0MOxVpc?H@hyeOL7lecgj92C`^-MfIT0H{Ps%0n!ij zZ^W;SgR}j>hFz%E+tXc>4Zm5RE|?w_jaVWMiCYSP6grD8*h%jp#p(`DiMG0^S4Q6V z&(n?=$?4vuES+PStWx~gtW}JHrq8uOM!*Y|oT0qlR4iLA%zfybjCig`?M|S;yyxBdD*~JaW?K0>#6u$+*S|c| zM&|9G6sm^`Tw|I43D?)=lY5zQU+8#1ciaUrd?9OK_UDJ13MP-<<@%IgWUZvYuVk->KstwC2tKYH*ca73E;Rhkza3IG=Xquv5Mf6euQ>v&!`M!Y5z- zLE@S45|$R!868g(mPN`U+wYsoWc0xTH1#!NCt)eGEZz2QK^KtRI{=EFEtF{iXT0rQ z=uct#UgVckGyp3MHGk;}Uxt+v+_C#*lXJhBIr1Kr=uchWXQn z7pv|_qPvd=b^Lb@3(fKBi{x04cGikA4u|D<&}OBy@T7H-xyzM(Y4F&WpG_*Y9-da2 z>*6NUvVOA=|K<1CYr1vU8iz+eFcy-M_#C^&yb1=LS%Qf;eWI~du`KoV23czTz5h2a zzr3z|0g9RwHRB@yOZ)oZbm_S(Xzr|j?#`|Y_Oo{+^L!&9rw?6cGaKDLCJ=VIfK zPP4#-GbtM~8rfR6BNlaky;>ajP)P}w)xLRnEWce>7-J%M?*4|6OjN~_p1j9Bkhl?H zQR@C4;6OfBIH^|IN@f|`8DhL~ICJ8?$2xY?zcmLe^H@dZ+Mtd;X=u^lTX6D^ED0m< z=}NWHR}`*4`w(SpnC8h|`?hIDpGu_17w%hyC9&a#O1u+~>L1Y!YOeEp-?g{l3FF=fEN}r3>sfdzs_u{@Vp#{;tAU7w+yB}?j$!?FAH7q_ipA#hQayKzCAALk& za`fDv6wtZs6Lp_QmGwa2*Gp3i^mB}B77gOroj88u@^>d_Sj7pv%N2Vv0vV$?IVR$6 z(S84@d)59pI0bQQv89%l11s(m(EblsR9Nv43e-TSWaK#^oBmCBRB}2TaGCS8?gYk> zhV6=6EQ7Xnv7}YCJ#|O1LFtrr!Yr>@W35v(LVbXvt_rHTfS!qt zwXK$&{9Lo2qO}G&dfkwL{3x73V8*3j)?FE121AtkR9cmA;F(uv+=K}KsQ0g|`A}eD zfp(H|tCmiQhiAlE`EFVbx^_mEoJRtSxEwIQ4)GuV1C$-% z0%IkDL*h5%7u{<6R{#u0r!K`6D-J+;P^TfD9S87IMqv6oNq+Ud#7FDb6VDjt#OF~d z575EY+0~g27+8x3`$Hc5MOXIlE>WLG4mhK-!+Y6*=0b5(?o~ZW3Fl=*@z5Vt%QRiB z$(z!co3{)NGhiB{rYcXnpAt@tJ!zOJ z!IHXxDIg29;Gh^OZB7#I+4mH^A`aK~k^rMPp`yOKP&p5Wbc=g2+cSAGP6PL(z`R~Y zC@<;eeMu$u()imkmOn8Z01g?p%a1gO#{?WoZ{|MduK?KzVBhE+sZ>`7EXX^4GcaCb+Yy)dejyv5-AJxwx=#J0X|$zGbW1O;;Dy+_dAj=cHo) zLl`CP;a4`5^x$C=iy9ht%UGT$J-^H+8QgvQRg`cP{FdhiVJ9oD;eVm4_w`!OBcY>l zGSectai_NokDN(>o`64<#BG73Gkb+iWob8QByDB26KfyViI3Ab`eS3iK5;O7;mCB; zfTiVQ2b-*)yk0ntdHl^q*3}n?Ok>7D(T-r%vg(?~=>~lZ)Yav#XlRbmPxYi;T@~TO zM!DCZt!WD6+@#9&l?$Ji&Aqk%O(txE#uj|uDf%Qb60qMtue!KPQk9vH{&jAC3`=1Q zza4m*Fb$7pJbAG$)%jFxc^0j|JJ-FcdFHD|T|4tdw9Pw&(v-|zOqerMH`4pC^N_nW zx4V_QSzCnEMCvO}g`x`%eyM74TG@&xCD)L)An!P($;Y$j2jTnn-l8f7C9jQAj@MrS zBIHRIxNgQr4`;s*cLxr>Y5@d4+BM`kv&fCR-;gNPsZ~qyU;Oj^?NVq^$h&cvlB>Xk z7W<;=m67@eSYE-$7GP@vkA=(;nKEF@)7dcVyyssK{bl%j#RZ0%TpIA4^4^@(_NWKN znir2LpGye>aapcpGm3vDH;JhBo@y0*Fuhq?x{+Jb7G40q`&r964~lSGKKBma8i=E* zoYbzP<@dwN(?S=LvA-K-+$?r-eS7Ldo^;VHK`7zQ2^#iZ@$f5X@ZqyB^n?vp^%0r0 zyX)^&3p z$=*13Bpk7Q2lBr;58r3O_o$hl(NJ4*^nfl`L(rgTlV6XC#*aNHtY3dj;Jd-blW(O% z4%?>FP5`{_4XZzK661P2*eIeRSEu_~kj85sIo1lfP;~4GK5EZ$ALL!4cqYIgzng+h zCFJ7~gCw$z!6h5cRCYWUZxQiSNkEH-?1gAD<*}KUQVPC|MubFZ>}f zOQ77bOh{8Y&=6fd%hEP**)m|>tFu~i~#662*(|bmmUe1XQ;#4W3gKC{Ybk3dKpnRWgxcJ)hzr2wHBCwHe>sD9*zvdRA%ox{op1=khUC5%HWvH^Ow-Qf}fb!4bb z+h$JD@aIB$Cmu78b}B}@E$ynf%#aTukK$#Q4|M~~?hk2+G82d$tjq*bi|}N%{R$w{ z5#&8gA0YC*Hfmbur0_@M81u70Ed)kpO!{yA7gGw%R+~W4h z6|8l>36!6W8PIU}a$|Yd^}C)%K6NMcO{FskdNrzhhpDf5)n1tp=94FIBLCuL{7Qxo zw3opT>4WjAbpBe)G?)KTU|591`}SAj4SzN(@J<{Le&n9dxlrRoPA8!-9xd!JO;%t- zx(Ne+@1gvIP(eQ>pbyP9j^o9@cB_u)U}~!imrtupUD0+}jQ`kP0F}M>cU6+tTT~jbW9R01|BK|ZeZ%LYD zUKh=_{<9XPzy;xYtM%KaNtb=c>28uy{G{xBnj+b{AF4TBT4Xm&F zf5@V8#@FkYl8*n%u8L2;Gu8C{I6wGxP1v@t;RnBo)an7^{7=Qc%!fLR&opUr;i0Ejd5)T1|pfrcXv*YU2g?%Pz<_%SKJ>?}`t-5*H;&NZDwmgGI~*o=hk!-^|JI&gA41 zuG1>oKMdqEthd!dOQ+rrk`fT>IR8!a+mycx-`Up2iCx}$zQCL*^?Df$y;Sb+G z-0QVrQubEK=)owlme1KdO54&d^`NK}x3@rK5){1_I%hIARH)xbm9oV+$j=0Xj9!~G z36VVM`S2e_HI@GDK^Y;j>Yev(T{e;dFE;(gZO89zh*;3lWXJ+D9AL;vD|VQ*N)bJv z+7?Q*+lNQV=L|Hk8o(7S72G(hBq`e>|%68H560epKYTR8+m2mix z3@|Rb+LNZALP%ITSWPd)F6Jl(%D>6c&szZwH@PDTyG~cm^&bhlxevuG4ircQMP@C+ z9kx6Fz21d=Px>w<(+*AQ@^9^B33@)O{vW071=0&ifXrvqoVe1|+C_*JRS@Ncg& z9``$+^;3C`KiO*N@1Elx(-hJwYl%LBuZGn&AiwNo8Y{gJ?y2bC*_MeMm-^A_PVR9~ z&(Z?-hbIFo-~Cv8QB{a`-hgf?y#}xN;DOdyFMzLxlZ>}Vi_1FsjmX@^_A-v7lU)m; z-G5v61+he<*y=iu)qmUS567oxyfU~~o*wj$>{#+y_+DLqM{)W4vQbb6vo<`~oRwDF z`uMBBjnKT8LytkXe|!X}3!0t41NX@HOSY60t;!NZWScIWVpJJEtp7_3FH$VNo|FAq za^Q;8fUf#)Q-i$9c`5pxUk7~sz;v2M(3_UYhdMXk?cPj!mh$XhY~?rEZFvz>-jl36 z*^MjMuQgyJ!8d=E#?j3-eBbC1-I_|&@-yPu%Jc`wrRd^g1s5kjWU|+LDW$0#+BD(&O4}55cGX(H3 zzYhIg`!#Btm=<~q^&LXWIPtfx_+f)M=U*`Dd|u>!T|p0FEiD0A?u0boFI4ctIagf=c$1HuXj$kDrX*MpL^figBM^z>?b;!A_2lepZ zOVmaF_Zq1qkyF50l%W_k<)GP+Qo{?()VPWCoqE$l#-?vK)Nxp;I!=M2kZ zV6{rq>zp@1muZPoy<1;oh=N;L2d{ge=1CkJgxE)(poB-gCjb@$QwR%aw{N9h|3yT~ z)o1{5tVA{{*L=pu_k$tU6o;kH7Hzia9o>AIE){*L>EJ0;Ug22Fz2(TtI74AE^vHwF z+`R|zbJ0Ed);$G3%+x-4?vvx>IE%@w7p@?==!orVSB~(^C$_>sX*K_4Y)j;-5SRP( zXRMycs;XX+L@L5?l<--pn0c(r5y2b(&-e-VmB|0U1;|kfj0^CUC?~o@=E|#56{QQA z8WBf_xG{<9!is7@b2PUG(^8#pGN{dKG2!HW_=)KuY#3(cfdBkw%{^{=b*OtR$+dNf z*9>Na)(MX5T#jVT*5qX6N-<%2t!NWpm=`(z=<%WV%|5Ik2_c)v!J%e8-y$tGY(zjS zr!n;@RLSb|$-L5gdG6i zGbY^O@lMwG2jG*Q|^czi5vKaKAiCi=%|89@hIa36*+hfZpI=*~hs-1NOz>W3_psnCuE6 zl{S-h6xP4=;?+7%;dyndl##V6vn6di?zE48nfuJe760gZ?!AhqsSO)Dx+VF+% zeIZ5!t(0g4MVh*(MUFQ^VvN@<&tqXFx3j@Kod?5TO!6%o_g1%^-fNJAYeT}SsE4JK zlTZwF1BLJnZ)|KT^NlE=XXR3_!gzxUG^}*YPfVW$5L2bd2l69(s;J<6)|&=9e9fzi z4y)Hy<;`o%r^C zuk{=7UUoYWdCt8Id)(7Gk$PB9U%R?w$uS-Y)h2AOI`=16?JLK9h>5nqzWVj9=r<)| z{1wZyBOY`4v6Qxw9R>jheM@uqO6I%ZXL;q@QQ!})4E~MctZ|HhcAamOBk>M(dS?eh zD@ezUC+1Y=wKg=3ARSRf6Jeq`>a1cvA(xan^nQpA+@fqTFv7xE;wkIljwh%>fN*$R zu+vVYLi+aG9NG3|>BJ|dTlv(^;l_83TIM47a~{+9o&904gEJC^4~h8Irk^54lDWh% zPwRE(GJF}!eAx(|n$&(}(gt{V$MKU1$3{a=cp@%KH*()!!uk|0P~`|BZ|n8&r}@3( z``Y8WSc>hBC{}d+6JxQ*H5Mw_A_&T9T_4yS{UIs8)j;V^ZoQwud80`EuKbI&W8K(D zI15QwvU1@B+eZ#|IY6sSmBEDde!YWKdEN89kSL*REMcQC$rc}IdbY>9lI{_#p}*%a zH5ckbf+)d`-a2s2TfQ-;XtSVb-T9b2TA;G5J#HXW{lq`ZdWYlB(fy_gv7bO6mcO-T z0riCCsNYztGr>Nm_}{;=BE7mVvwKv~>{p1vf#vLW9=X6_{$gUP>G{PUO7y#Ca=kyJ zprRc4sl5lV>W!fSxt~w&Ar{Z%Nm+#vx)a&vj9Rz>dU3~020P7K=ZBd}6b2M5zQv^? zq{=nlm`-_aTNH~QG;!69N1TIf-<^I+0NmyjC89Ni65(1LH#QV9bP)VE&@;>816l&4 z;qv&GMkh*CO7uao{d@X?3L)a~SNX``gjP@-fs44k=?iE-){wB^ASP~Zh> zfwlYN6xH({D1toy7WXG-{ArUMLorxqBLT@YJ){K-sgu+dC;#S9-z zIRZPjIF(9&K2#7ZGA{r6PHI1PnteA9c{y2fUsnBX-9ih|AE!2W&^(7a$8`(QF0NPd zy;o!|w;Elu@dW$p+ENi~8n!?m{9AZ~E0%HtHG+gg^=^GyaHOhKpYpc{*|4v51?mPw z&sat?mZ*vYYpyNw@^vGuxK8UpfYPiCUm{bPD~ycP9&EO44u?C%?9FmYD7=d^}x-)cea z*C$!rvE#0(Tev%UN#53a1S(8Da5qj0bV|!huvb1FfICiW_I>YQ0>iG(diTPN)N;6Q zYwiZN!H+%8{Gp%m)4IyyUyq|RVhshbBC;j4$E&4)H)FSS>PGjY`XJQeKZ0j%!NTeD zg51`~M)A?<012ahe3&(g42XwvS^a)DoV@tUH;E}M+a7$+riT%A;&p+V!EMdi0taCn zjZcnHn7vW`6Z&v*zR$4}awJa3a~J*-2xSL+AeDdhS{_qN6dF%6YB7g{hACy|MNN?w zT)c*WfJbEiFeNx~O) zjzsf&-$sS3_RpNnJ?AAkZ!TsTM|g4%-{=wCqLsD_o8Prm9VZWwWm3?>p5RM64*EkW z2-PAPLd?#Ox#|MAlgS&|{A0SGIkV9kF zl-SmH1$sfOL)(Ir+nn`p$p=+*@aK#rtQ?uvNoma6?{z^y+@h6U<-BR`yP52}Xnc7` z1vK$-FH-e(Pf+|QmV0lMeM2e60q>b>Br5If6;_kVpss z9i6xdv)99^-rJEsGOMLL-1=AHjgE&KIv&?rV3F~;ir=(*JNV)j-d*|@4|mQdYU+@< zHr5VvSnb^5iE=c1l`E`qbCUhq@yU)LF<~#wxxp6az|g6e5POYbyt(e?mS-9dG{nB6 z@T)E(bXnHfp7>Rm5jQm`6}Nd($x0-?vVfY;s;^TmKx+^P#_(AP;ktw{q-Cya>$n`q zqgr&nmFTa|>X~n=WC?*6#;|j{MY|G1l7CXnKOEmDoCUBqcDhsMT#6!3p|8KaJ$hv^ zYdPt5zH9{xq0$iMePpxd%2!?+&Tg;%1y&sBR^n;POViwq)b<8lUz0X zbKGK5^;ivcja9xrL|D_q;$4<+=)e^(+)};yc=Ofzr@L1C_uLx1Uh#CvmEP1<;tPFQ zjk~%`A&HsEE)nt|+`h1Uh?|s$WPv~;?!s^%oueH>tpPwa{NSUQN<@;V zB_0!VNSxGOJKm$Ays|`BZ6CY6V%_MK23Z=lO>Criy6A;)(O z$A1`!^6T|Di7U|f?*km_tgUF_sWF1bBNO+P8K5n-*q(h0j04(V6s8{igP$A!?YRu% zYjb`BQdGPTpj4aC@Rp;jQa>1*{nGzdy6kv|nzH9SV&P7nYTR?*DIp$#qS(A3d^|

#_we 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 Dn5!O> literal 0 HcmV?d00001 From 319d59296eeb1cd63a7b15edf6733e97ed9c2e44 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 14 May 2022 06:44:22 +1000 Subject: [PATCH 10/48] Support loading images into Windows tray --- .../frontend/desktop/windows/traymenu.go | 31 ++++--------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/v2/internal/frontend/desktop/windows/traymenu.go b/v2/internal/frontend/desktop/windows/traymenu.go index 72c91d7d8..a2efee650 100644 --- a/v2/internal/frontend/desktop/windows/traymenu.go +++ b/v2/internal/frontend/desktop/windows/traymenu.go @@ -5,9 +5,7 @@ package windows import ( "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32" - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32" "github.com/wailsapp/wails/v2/pkg/menu" - "golang.org/x/sys/windows" "log" "sync" "unsafe" @@ -37,31 +35,14 @@ func (w *Win32TrayMenu) SetMenu(menu *menu.Menu) {} func (w *Win32TrayMenu) SetImage(image *menu.TrayImage) { data := w.newNotifyIconData() - //var iconBuffer bytes.Buffer - //bitmap := image.GetBestBitmap(1, false) - //iconData, err := ResizePNG(bitmap, 32) - //if err != nil { - // log.Fatal(err.Error()) - //} - icon, err := win32.LoadImage( - 0, - windows.StringToUTF16Ptr("icon-44.ico"), - w32.IMAGE_ICON, - 32, - 32, - 0x00000040|0x00000010) - if err != nil && err != windows.ERROR_SUCCESS { - panic(err) + bitmap := image.GetBestBitmap(1, false) + icon, err := win32.CreateIconFromResourceEx(uintptr(unsafe.Pointer(&bitmap[0])), uint32(len(bitmap)), true, 0x30000, 0, 0, 0) + if err != nil { + log.Fatal(err.Error()) } - data.HIcon = icon - // - //icon, err := win32.CreateIconFromResourceEx(uintptr(unsafe.Pointer(&bitmap[0])), uint32(len(bitmap)), true, 0x30000, 0, 0, 0) - //if err != nil { - // log.Fatal(err.Error()) - //} data.UFlags |= win32.NIF_ICON - //data.HIcon = icon - if _, err := win32.NotifyIcon(win32.NIM_ADD, data); err != nil { + data.HIcon = icon + if _, err := win32.NotifyIcon(win32.NIM_MODIFY, data); err != nil { log.Fatal(err.Error()) } } From a11655c45203a8ec0870fa3101ff97f610e65f0f Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 9 Jul 2022 22:55:03 +1000 Subject: [PATCH 11/48] Merge master --- .../frontend/desktop/windows/win32/consts.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/v2/internal/frontend/desktop/windows/win32/consts.go b/v2/internal/frontend/desktop/windows/win32/consts.go index 66f648021..e976001f6 100644 --- a/v2/internal/frontend/desktop/windows/win32/consts.go +++ b/v2/internal/frontend/desktop/windows/win32/consts.go @@ -12,12 +12,12 @@ type HRESULT int32 type HANDLE uintptr var ( - moduser32 = syscall.NewLazyDLL("user32.dll") - procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") - procGetWindowLong = moduser32.NewProc("GetWindowLongW") - procSetClassLong = moduser32.NewProc("SetClassLongW") - procSetClassLongPtr = moduser32.NewProc("SetClassLongPtrW") - procShowWindow = moduser32.NewProc("ShowWindow") + moduser32 = syscall.NewLazyDLL("user32.dll") + procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") + procGetWindowLong = moduser32.NewProc("GetWindowLongW") + procSetClassLong = moduser32.NewProc("SetClassLongW") + procSetClassLongPtr = moduser32.NewProc("SetClassLongPtrW") + procShowWindow = moduser32.NewProc("ShowWindow") procLookupIconIdFromDirectoryEx = moduser32.NewProc("LookupIconIdFromDirectoryEx") procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx") procCreateIconIndirect = moduser32.NewProc("CreateIconIndirect") @@ -191,7 +191,6 @@ const ( WM_PENWINFIRST = 896 WM_PENWINLAST = 911 WM_POWER = 72 - WM_POWERBROADCAST = 536 WM_PRINT = 791 WM_PRINTCLIENT = 792 WM_QUERYDRAGICON = 55 From 823c36523609414b8dc2b77ff88db3ce7c336e12 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 23 Sep 2022 17:29:54 +1000 Subject: [PATCH 12/48] Application refactor --- v2/internal/app/app.go | 33 +++++++++++++++++++ v2/internal/app/app_bindings.go | 23 ++++--------- v2/internal/app/app_darwin.go | 16 --------- v2/internal/app/app_debug.go | 1 - .../{app_not_debug.go => app_debug_not.go} | 1 - v2/internal/app/app_default_linux.go | 24 -------------- ..._default_darwin.go => app_default_unix.go} | 6 ---- v2/internal/app/app_default_windows.go | 6 ---- v2/internal/app/app_dev.go | 23 ------------- v2/internal/app/app_linux.go | 16 --------- ...ot_obfuscated.go => app_obfuscated_not.go} | 0 v2/internal/app/app_preflight_unix.go | 12 +++++++ ...pp_windows.go => app_preflight_windows.go} | 1 - v2/internal/app/app_production.go | 22 ------------- v2/wails.go | 9 +++-- 15 files changed, 58 insertions(+), 135 deletions(-) create mode 100644 v2/internal/app/app.go delete mode 100644 v2/internal/app/app_darwin.go rename v2/internal/app/{app_not_debug.go => app_debug_not.go} (80%) delete mode 100644 v2/internal/app/app_default_linux.go rename v2/internal/app/{app_default_darwin.go => app_default_unix.go} (71%) delete mode 100644 v2/internal/app/app_linux.go rename v2/internal/app/{app_not_obfuscated.go => app_obfuscated_not.go} (100%) create mode 100644 v2/internal/app/app_preflight_unix.go rename v2/internal/app/{app_windows.go => app_preflight_windows.go} (96%) diff --git a/v2/internal/app/app.go b/v2/internal/app/app.go new file mode 100644 index 000000000..7853f3e3a --- /dev/null +++ b/v2/internal/app/app.go @@ -0,0 +1,33 @@ +package app + +import ( + "context" + "github.com/wailsapp/wails/v2/internal/frontend" + "github.com/wailsapp/wails/v2/internal/logger" + "github.com/wailsapp/wails/v2/internal/menumanager" + "github.com/wailsapp/wails/v2/pkg/options" +) + +// App defines a Wails application structure +type App struct { + frontend frontend.Frontend + logger *logger.Logger + options *options.App + + menuManager *menumanager.Manager + + // Indicates if the app is in debug mode + debug bool + + // OnStartup/OnShutdown + startupCallback func(ctx context.Context) + shutdownCallback func(ctx context.Context) + ctx context.Context +} + +// Shutdown the application +func (a *App) Shutdown() { + if a.frontend != nil { + a.frontend.Quit() + } +} diff --git a/v2/internal/app/app_bindings.go b/v2/internal/app/app_bindings.go index f0e059213..b87f41cd8 100644 --- a/v2/internal/app/app_bindings.go +++ b/v2/internal/app/app_bindings.go @@ -1,5 +1,4 @@ //go:build bindings -// +build bindings package app @@ -16,23 +15,17 @@ import ( "github.com/wailsapp/wails/v2/pkg/options" ) -// App defines a Wails application structure -type App struct { - logger *logger.Logger - appoptions *options.App -} - func (a *App) Run() error { // Create binding exemptions - Ugly hack. There must be a better way bindingExemptions := []interface{}{ - a.appoptions.OnStartup, - a.appoptions.OnShutdown, - a.appoptions.OnDomReady, - a.appoptions.OnBeforeClose, + a.options.OnStartup, + a.options.OnShutdown, + a.options.OnDomReady, + a.options.OnBeforeClose, } - appBindings := binding.NewBindings(a.logger, a.appoptions.Bind, bindingExemptions, IsObfuscated()) + appBindings := binding.NewBindings(a.logger, a.options.Bind, bindingExemptions, IsObfuscated()) err := generateBindings(appBindings) if err != nil { @@ -41,8 +34,6 @@ func (a *App) Run() error { return nil } -func (a *App) Shutdown() {} - // CreateApp creates the app! func CreateApp(appoptions *options.App) (*App, error) { // Set up logger @@ -50,8 +41,8 @@ func CreateApp(appoptions *options.App) (*App, error) { myLogger.SetLogLevel(appoptions.LogLevel) result := &App{ - logger: myLogger, - appoptions: appoptions, + logger: myLogger, + options: appoptions, } return result, nil diff --git a/v2/internal/app/app_darwin.go b/v2/internal/app/app_darwin.go deleted file mode 100644 index 939f724a4..000000000 --- a/v2/internal/app/app_darwin.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build darwin && !bindings -// +build darwin,!bindings - -package app - -import ( - "github.com/wailsapp/wails/v2/internal/logger" - "github.com/wailsapp/wails/v2/pkg/options" -) - -func PreflightChecks(options *options.App, logger *logger.Logger) error { - - _ = options - - return nil -} diff --git a/v2/internal/app/app_debug.go b/v2/internal/app/app_debug.go index bfcdd13b4..c14bedec1 100644 --- a/v2/internal/app/app_debug.go +++ b/v2/internal/app/app_debug.go @@ -1,5 +1,4 @@ //go:build debug -// +build debug package app diff --git a/v2/internal/app/app_not_debug.go b/v2/internal/app/app_debug_not.go similarity index 80% rename from v2/internal/app/app_not_debug.go rename to v2/internal/app/app_debug_not.go index b20a7c80f..04f841ede 100644 --- a/v2/internal/app/app_not_debug.go +++ b/v2/internal/app/app_debug_not.go @@ -1,5 +1,4 @@ //go:build !debug -// +build !debug package app diff --git a/v2/internal/app/app_default_linux.go b/v2/internal/app/app_default_linux.go deleted file mode 100644 index 2a2f1770d..000000000 --- a/v2/internal/app/app_default_linux.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:build !dev && !production && !bindings && linux -// +build !dev,!production,!bindings,linux - -package app - -import ( - "fmt" - - "github.com/wailsapp/wails/v2/pkg/options" -) - -// App defines a Wails application structure -type App struct{} - -func (a *App) Run() error { - return nil -} - -func (a *App) Shutdown() {} - -// CreateApp creates the app! -func CreateApp(_ *options.App) (*App, error) { - return nil, fmt.Errorf(`Wails applications will not build without the correct build tags.`) -} diff --git a/v2/internal/app/app_default_darwin.go b/v2/internal/app/app_default_unix.go similarity index 71% rename from v2/internal/app/app_default_darwin.go rename to v2/internal/app/app_default_unix.go index b31a002fd..01a3225c7 100644 --- a/v2/internal/app/app_default_darwin.go +++ b/v2/internal/app/app_default_unix.go @@ -1,5 +1,4 @@ //go:build !dev && !production && !bindings && darwin -// +build !dev,!production,!bindings,darwin package app @@ -9,15 +8,10 @@ import ( "github.com/wailsapp/wails/v2/pkg/options" ) -// App defines a Wails application structure -type App struct{} - func (a *App) Run() error { return nil } -func (a *App) Shutdown() {} - // CreateApp creates the app! func CreateApp(_ *options.App) (*App, error) { return nil, fmt.Errorf(`Wails applications will not build without the correct build tags.`) diff --git a/v2/internal/app/app_default_windows.go b/v2/internal/app/app_default_windows.go index a05ef2a53..b1b66a081 100644 --- a/v2/internal/app/app_default_windows.go +++ b/v2/internal/app/app_default_windows.go @@ -1,5 +1,4 @@ //go:build !dev && !production && !bindings && windows -// +build !dev,!production,!bindings,windows package app @@ -10,15 +9,10 @@ import ( "github.com/wailsapp/wails/v2/pkg/options" ) -// App defines a Wails application structure -type App struct{} - func (a *App) Run() error { return nil } -func (a *App) Shutdown() {} - // CreateApp creates the app! func CreateApp(_ *options.App) (*App, error) { result := w32.MessageBox(0, diff --git a/v2/internal/app/app_dev.go b/v2/internal/app/app_dev.go index 6951e6644..b61876213 100644 --- a/v2/internal/app/app_dev.go +++ b/v2/internal/app/app_dev.go @@ -1,5 +1,4 @@ //go:build dev -// +build dev package app @@ -14,7 +13,6 @@ import ( "path/filepath" "github.com/wailsapp/wails/v2/internal/binding" - "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/frontend/desktop" "github.com/wailsapp/wails/v2/internal/frontend/devserver" "github.com/wailsapp/wails/v2/internal/frontend/dispatcher" @@ -27,27 +25,6 @@ import ( "github.com/wailsapp/wails/v2/pkg/options" ) -// App defines a Wails application structure -type App struct { - frontend frontend.Frontend - logger *logger.Logger - options *options.App - - menuManager *menumanager.Manager - - // Indicates if the app is in debug mode - debug bool - - // OnStartup/OnShutdown - startupCallback func(ctx context.Context) - shutdownCallback func(ctx context.Context) - ctx context.Context -} - -func (a *App) Shutdown() { - a.frontend.Quit() -} - func (a *App) Run() error { err := a.frontend.Run(a.ctx) if a.shutdownCallback != nil { diff --git a/v2/internal/app/app_linux.go b/v2/internal/app/app_linux.go deleted file mode 100644 index 154cd38e4..000000000 --- a/v2/internal/app/app_linux.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build linux && !bindings -// +build linux,!bindings - -package app - -import ( - "github.com/wailsapp/wails/v2/internal/logger" - "github.com/wailsapp/wails/v2/pkg/options" -) - -func PreflightChecks(options *options.App, logger *logger.Logger) error { - - _ = options - - return nil -} diff --git a/v2/internal/app/app_not_obfuscated.go b/v2/internal/app/app_obfuscated_not.go similarity index 100% rename from v2/internal/app/app_not_obfuscated.go rename to v2/internal/app/app_obfuscated_not.go diff --git a/v2/internal/app/app_preflight_unix.go b/v2/internal/app/app_preflight_unix.go new file mode 100644 index 000000000..a135d7234 --- /dev/null +++ b/v2/internal/app/app_preflight_unix.go @@ -0,0 +1,12 @@ +//go:build unix && !bindings + +package app + +import ( + "github.com/wailsapp/wails/v2/internal/logger" + "github.com/wailsapp/wails/v2/pkg/options" +) + +func PreflightChecks(_ *options.App, _ *logger.Logger) error { + return nil +} diff --git a/v2/internal/app/app_windows.go b/v2/internal/app/app_preflight_windows.go similarity index 96% rename from v2/internal/app/app_windows.go rename to v2/internal/app/app_preflight_windows.go index affc33736..1b71b8b19 100644 --- a/v2/internal/app/app_windows.go +++ b/v2/internal/app/app_preflight_windows.go @@ -1,5 +1,4 @@ //go:build windows && !bindings -// +build windows,!bindings package app diff --git a/v2/internal/app/app_production.go b/v2/internal/app/app_production.go index cd1bfb933..f33149e26 100644 --- a/v2/internal/app/app_production.go +++ b/v2/internal/app/app_production.go @@ -6,7 +6,6 @@ import ( "context" "github.com/wailsapp/wails/v2/internal/binding" - "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/frontend/desktop" "github.com/wailsapp/wails/v2/internal/frontend/dispatcher" "github.com/wailsapp/wails/v2/internal/frontend/runtime" @@ -15,27 +14,6 @@ import ( "github.com/wailsapp/wails/v2/pkg/options" ) -// App defines a Wails application structure -type App struct { - frontend frontend.Frontend - logger *logger.Logger - options *options.App - - menuManager *menumanager.Manager - - // Indicates if the app is in debug mode - debug bool - - // OnStartup/OnShutdown - startupCallback func(ctx context.Context) - shutdownCallback func(ctx context.Context) - ctx context.Context -} - -func (a *App) Shutdown() { - a.frontend.Quit() -} - func (a *App) Run() error { err := a.frontend.Run(a.ctx) if a.shutdownCallback != nil { diff --git a/v2/wails.go b/v2/wails.go index dec83b810..45334552a 100644 --- a/v2/wails.go +++ b/v2/wails.go @@ -9,6 +9,9 @@ import ( "github.com/wailsapp/wails/v2/pkg/options" ) +// This is the global application instance +var application *app.App + // Run creates an application based on the given config and executes it func Run(options *options.App) error { @@ -27,16 +30,16 @@ func Run(options *options.App) error { return err } - mainapp, err := app.CreateApp(options) + application, err = app.CreateApp(options) if err != nil { return err } signal.OnShutdown(func() { - mainapp.Shutdown() + application.Shutdown() }) signal.Start() - return mainapp.Run() + return application.Run() } From 26c6881ed3907d06d929c8e83e31d338826854c1 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 24 Sep 2022 07:52:19 +1000 Subject: [PATCH 13/48] Add issue translator (#1891) --- .github/workflows/issue-translator.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/issue-translator.yml diff --git a/.github/workflows/issue-translator.yml b/.github/workflows/issue-translator.yml new file mode 100644 index 000000000..ad9d56c35 --- /dev/null +++ b/.github/workflows/issue-translator.yml @@ -0,0 +1,15 @@ +name: 'issue-translator' +on: + issue_comment: + types: [ created ] + issues: + types: [ opened ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: tomsun28/issues-translate-action@v2.6 + with: + IS_MODIFY_TITLE: false + CUSTOM_BOT_NOTE: The issue body's language is not English, translating it automatically... From 022fd9afff5300d83164b23131ddcae6b14a9125 Mon Sep 17 00:00:00 2001 From: Misite Bao Date: Sat, 24 Sep 2022 09:50:57 +0800 Subject: [PATCH 14/48] chore: update the label name in the issue template (#1893) --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/documentation.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1c31a1cba..238453d3b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,7 +1,7 @@ name: Bug Report description: Create a report to help us improve # title: "" -labels: ["bug"] +labels: ["Bug"] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml index 5124ea777..c1259587b 100644 --- a/.github/ISSUE_TEMPLATE/documentation.yml +++ b/.github/ISSUE_TEMPLATE/documentation.yml @@ -1,7 +1,7 @@ name: Documentation description: Report an issue related to documentation. # title: "" -labels: ["documentation"] +labels: ["Documentation"] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 292a039a2..b346c0bdc 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,7 +1,7 @@ name: Feature request description: Suggest an idea for this project # title: "" -labels: ["enhancement"] +labels: ["Enhancement"] body: - type: markdown From 2940a9e7ef3624fccd080ae415d636681f1ef0fe Mon Sep 17 00:00:00 2001 From: Arif Ali <51419655+arifali123@users.noreply.github.com> Date: Fri, 23 Sep 2022 22:05:18 -0700 Subject: [PATCH 15/48] obfuscated instead of obfuscate in the docs (#1895) the option in the docs is the wrong flag you have to add a d at the end --- website/versioned_docs/version-v2.0.0/guides/obfuscated.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/versioned_docs/version-v2.0.0/guides/obfuscated.mdx b/website/versioned_docs/version-v2.0.0/guides/obfuscated.mdx index c062d0f46..2e7906c40 100644 --- a/website/versioned_docs/version-v2.0.0/guides/obfuscated.mdx +++ b/website/versioned_docs/version-v2.0.0/guides/obfuscated.mdx @@ -5,13 +5,13 @@ Wails includes support for obfuscating your application using [garble](https://g To produce an obfuscated build, you can use the `-obfuscate` flag with the `wails build` command: ```bash -wails build -obfuscate +wails build -obfuscated ``` To customise the obfuscation settings, you can use the `-garbleargs` flag: ```bash -wails build -obfuscate -garbleargs "-literals -tiny -seed=myrandomseed" +wails build -obfuscated -garbleargs "-literals -tiny -seed=myrandomseed" ``` These settings may be persisted in your [project config](../reference/project-config). From cfb55f7c5edd358e4e48ada6fafdb6bca03c608f Mon Sep 17 00:00:00 2001 From: stffabi Date: Sat, 24 Sep 2022 10:03:16 +0200 Subject: [PATCH 16/48] [assetHandler] Remove redundant log prefix (#1896) --- v2/internal/frontend/assetserver/assethandler.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/v2/internal/frontend/assetserver/assethandler.go b/v2/internal/frontend/assetserver/assethandler.go index f30869c88..254f88e2c 100644 --- a/v2/internal/frontend/assetserver/assethandler.go +++ b/v2/internal/frontend/assetserver/assethandler.go @@ -71,11 +71,11 @@ func (d *assetHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { filename = indexHTML } - d.logDebug("[AssetHandler] Loading file '%s'", filename) + d.logDebug("Loading file '%s'", filename) if err := d.serveFSFile(rw, filename); err != nil { if os.IsNotExist(err) { if handler != nil { - d.logDebug("[AssetHandler] File '%s' not found, serving '%s' by AssetHandler", filename, req.URL) + d.logDebug("File '%s' not found, serving '%s' by AssetHandler", filename, req.URL) handler.ServeHTTP(rw, req) err = nil } else if filename == indexHTML { @@ -87,12 +87,12 @@ func (d *assetHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } if err != nil { - d.logError("[AssetHandler] Unable to load file '%s': %s", filename, err) + d.logError("Unable to load file '%s': %s", filename, err) http.Error(rw, err.Error(), http.StatusInternalServerError) } } } else if handler != nil { - d.logDebug("[AssetHandler] No GET request, serving '%s' by AssetHandler", req.URL) + d.logDebug("No GET request, serving '%s' by AssetHandler", req.URL) handler.ServeHTTP(rw, req) } else { rw.WriteHeader(http.StatusMethodNotAllowed) From 311dde474c0595a4badc7f0cb3d6d194d5b16e18 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 25 Sep 2022 21:17:15 +1000 Subject: [PATCH 17/48] [windows] refactor out main loop. Create new application struct. Refactor assethandler/assetserver signatures. --- v2/internal/app/app.go | 8 ++ v2/internal/app/app_dev.go | 2 + v2/internal/app/app_production.go | 2 + .../frontend/assetserver/assethandler.go | 6 +- .../frontend/assetserver/assetserver.go | 6 +- .../frontend/desktop/windows/frontend.go | 15 +++- v2/internal/frontend/desktop/windows/theme.go | 2 +- .../frontend/desktop/windows/window.go | 15 ++-- v2/internal/frontend/frontend.go | 4 +- v2/pkg/application/application.go | 75 +++++++++++++++++++ v2/{ => pkg/application}/init.go | 4 +- v2/{ => pkg/application}/init_windows.go | 7 +- v2/pkg/options/options.go | 4 +- v2/wails.go | 36 +-------- 14 files changed, 123 insertions(+), 63 deletions(-) create mode 100644 v2/pkg/application/application.go rename v2/{ => pkg/application}/init.go (51%) rename v2/{ => pkg/application}/init_windows.go (72%) diff --git a/v2/internal/app/app.go b/v2/internal/app/app.go index 7853f3e3a..f2821aaba 100644 --- a/v2/internal/app/app.go +++ b/v2/internal/app/app.go @@ -5,6 +5,7 @@ import ( "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/menumanager" + "github.com/wailsapp/wails/v2/pkg/menu" "github.com/wailsapp/wails/v2/pkg/options" ) @@ -31,3 +32,10 @@ func (a *App) Shutdown() { a.frontend.Quit() } } + +// SetApplicationMenu sets the application menu +func (a *App) SetApplicationMenu(menu *menu.Menu) { + if a.frontend != nil { + a.frontend.MenuSetApplicationMenu(menu) + } +} diff --git a/v2/internal/app/app_dev.go b/v2/internal/app/app_dev.go index b61876213..52bc11011 100644 --- a/v2/internal/app/app_dev.go +++ b/v2/internal/app/app_dev.go @@ -27,6 +27,8 @@ import ( func (a *App) Run() error { err := a.frontend.Run(a.ctx) + a.frontend.RunMainLoop() + a.frontend.WindowClose() if a.shutdownCallback != nil { a.shutdownCallback(a.ctx) } diff --git a/v2/internal/app/app_production.go b/v2/internal/app/app_production.go index f33149e26..245d375ce 100644 --- a/v2/internal/app/app_production.go +++ b/v2/internal/app/app_production.go @@ -16,6 +16,8 @@ import ( func (a *App) Run() error { err := a.frontend.Run(a.ctx) + a.frontend.RunMainLoop() + a.frontend.WindowClose() if a.shutdownCallback != nil { a.shutdownCallback(a.ctx) } diff --git a/v2/internal/frontend/assetserver/assethandler.go b/v2/internal/frontend/assetserver/assethandler.go index 254f88e2c..eef09779e 100644 --- a/v2/internal/frontend/assetserver/assethandler.go +++ b/v2/internal/frontend/assetserver/assethandler.go @@ -14,7 +14,6 @@ import ( "github.com/wailsapp/wails/v2/internal/fs" "github.com/wailsapp/wails/v2/internal/logger" - "github.com/wailsapp/wails/v2/pkg/options" ) //go:embed defaultindex.html @@ -33,8 +32,7 @@ type assetHandler struct { retryMissingFiles bool } -func NewAssetHandler(ctx context.Context, options *options.App) (http.Handler, error) { - vfs := options.Assets +func NewAssetHandler(ctx context.Context, vfs iofs.FS, AssetsHandler http.Handler) (http.Handler, error) { if vfs != nil { if _, err := vfs.Open("."); err != nil { return nil, err @@ -53,7 +51,7 @@ func NewAssetHandler(ctx context.Context, options *options.App) (http.Handler, e result := &assetHandler{ fs: vfs, - handler: options.AssetsHandler, + handler: AssetsHandler, } if _logger := ctx.Value("logger"); _logger != nil { diff --git a/v2/internal/frontend/assetserver/assetserver.go b/v2/internal/frontend/assetserver/assetserver.go index fb47f881d..d35c5a8f6 100644 --- a/v2/internal/frontend/assetserver/assetserver.go +++ b/v2/internal/frontend/assetserver/assetserver.go @@ -4,13 +4,13 @@ import ( "bytes" "context" "fmt" + iofs "io/fs" "net/http" "net/http/httptest" "strconv" "github.com/wailsapp/wails/v2/internal/frontend/runtime" "github.com/wailsapp/wails/v2/internal/logger" - "github.com/wailsapp/wails/v2/pkg/options" "golang.org/x/net/html" ) @@ -31,8 +31,8 @@ type AssetServer struct { appendSpinnerToBody bool } -func NewAssetServer(ctx context.Context, options *options.App, bindingsJSON string) (*AssetServer, error) { - handler, err := NewAssetHandler(ctx, options) +func NewAssetServer(ctx context.Context, vfs iofs.FS, AssetsHandler http.Handler, bindingsJSON string) (*AssetServer, error) { + handler, err := NewAssetHandler(ctx, vfs, AssetsHandler) if err != nil { return nil, err } diff --git a/v2/internal/frontend/desktop/windows/frontend.go b/v2/internal/frontend/desktop/windows/frontend.go index a5d13f4c5..59c3dcbdb 100644 --- a/v2/internal/frontend/desktop/windows/frontend.go +++ b/v2/internal/frontend/desktop/windows/frontend.go @@ -102,7 +102,7 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger. appBindings.DB().UpdateObfuscatedCallMap() } - assets, err := assetserver.NewAssetServer(ctx, appoptions, bindings) + assets, err := assetserver.NewAssetServer(ctx, appoptions.Assets, appoptions.AssetsHandler, bindings) if err != nil { log.Fatal(err) } @@ -180,11 +180,20 @@ func (f *Frontend) Run(ctx context.Context) error { f.frontendOptions.OnStartup(f.ctx) } }() - mainWindow.Run() - mainWindow.Close() + mainWindow.UpdateTheme() return nil } +func (f *Frontend) WindowClose() { + if f.mainWindow != nil { + f.mainWindow.Close() + } +} + +func (f *Frontend) RunMainLoop() { + _ = winc.RunMainLoop() +} + func (f *Frontend) WindowCenter() { runtime.LockOSThread() defer runtime.UnlockOSThread() diff --git a/v2/internal/frontend/desktop/windows/theme.go b/v2/internal/frontend/desktop/windows/theme.go index 897133026..e22f0c6cd 100644 --- a/v2/internal/frontend/desktop/windows/theme.go +++ b/v2/internal/frontend/desktop/windows/theme.go @@ -5,7 +5,7 @@ import ( "github.com/wailsapp/wails/v2/pkg/options/windows" ) -func (w *Window) updateTheme() { +func (w *Window) UpdateTheme() { // Don't redraw theme if nothing has changed if !w.themeChanged { diff --git a/v2/internal/frontend/desktop/windows/window.go b/v2/internal/frontend/desktop/windows/window.go index 1b511d34f..03c8807ce 100644 --- a/v2/internal/frontend/desktop/windows/window.go +++ b/v2/internal/frontend/desktop/windows/window.go @@ -99,7 +99,7 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope result.SetMaxSize(appoptions.MaxWidth, appoptions.MaxHeight) } - result.updateTheme() + result.UpdateTheme() if appoptions.Windows != nil { result.OnSuspend = appoptions.Windows.OnSuspend @@ -129,11 +129,6 @@ func NewWindow(parent winc.Controller, appoptions *options.App, versionInfo *ope return result } -func (w *Window) Run() int { - w.updateTheme() - return winc.RunMainLoop() -} - func (w *Window) Fullscreen() { w.Form.SetMaxSize(0, 0) w.Form.SetMinSize(0, 0) @@ -190,7 +185,7 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr { settingChanged := w32.UTF16PtrToString((*uint16)(unsafe.Pointer(lparam))) if settingChanged == "ImmersiveColorSet" { w.themeChanged = true - w.updateTheme() + w.UpdateTheme() } return 0 case w32.WM_NCLBUTTONDOWN: @@ -204,10 +199,10 @@ func (w *Window) WndProc(msg uint32, wparam, lparam uintptr) uintptr { w.themeChanged = true if int(wparam) == w32.WA_INACTIVE { w.isActive = false - w.updateTheme() + w.UpdateTheme() } else { w.isActive = true - w.updateTheme() + w.UpdateTheme() //} } @@ -303,6 +298,6 @@ func (w *Window) SetTheme(theme winoptions.Theme) { w.theme = theme w.themeChanged = true w.Invoke(func() { - w.updateTheme() + w.UpdateTheme() }) } diff --git a/v2/internal/frontend/frontend.go b/v2/internal/frontend/frontend.go index 1d178c4ce..74ff93153 100644 --- a/v2/internal/frontend/frontend.go +++ b/v2/internal/frontend/frontend.go @@ -10,7 +10,7 @@ import ( // FileFilter defines a filter for dialog boxes type FileFilter struct { DisplayName string // Filter information EG: "Image Files (*.jpg, *.png)" - Pattern string // semi-colon separated list of extensions, EG: "*.jpg;*.png" + Pattern string // semicolon separated list of extensions, EG: "*.jpg;*.png" } // OpenDialogOptions contains the options for the OpenDialogOptions runtime method @@ -65,6 +65,7 @@ type MessageDialogOptions struct { type Frontend interface { Run(context.Context) error + RunMainLoop() Hide() Show() Quit() @@ -105,6 +106,7 @@ type Frontend interface { WindowIsMinimised() bool WindowIsNormal() bool WindowIsFullscreen() bool + WindowClose() //Screen ScreenGetAll() ([]Screen, error) diff --git a/v2/pkg/application/application.go b/v2/pkg/application/application.go new file mode 100644 index 000000000..205ef6bfb --- /dev/null +++ b/v2/pkg/application/application.go @@ -0,0 +1,75 @@ +package application + +import ( + "github.com/wailsapp/wails/v2/internal/app" + "github.com/wailsapp/wails/v2/internal/signal" + "github.com/wailsapp/wails/v2/pkg/menu" + "github.com/wailsapp/wails/v2/pkg/options" +) + +// Application is the main Wails application +type Application struct { + application *app.App + options *options.App + + // running flag + running bool +} + +// NewWithOptions creates a new Application with the given options +func NewWithOptions(options *options.App) *Application { + if options == nil { + return New() + } + return &Application{ + options: options, + } +} + +// New creates a new Application with the default options +func New() *Application { + return &Application{ + options: &options.App{}, + } +} + +// SetApplicationMenu sets the application menu +func (a *Application) SetApplicationMenu(appMenu *menu.Menu) { + if a.running { + a.application.SetApplicationMenu(appMenu) + return + } + + a.options.Menu = appMenu +} + +// Run starts the application +func (a *Application) Run() error { + + err := applicationInit() + if err != nil { + return err + } + + application, err := app.CreateApp(a.options) + if err != nil { + return err + } + + a.application = application + + // Control-C handlers + signal.OnShutdown(func() { + a.application.Shutdown() + }) + signal.Start() + + a.running = true + + return a.application.Run() +} + +// Quit will shut down the application +func (a *Application) Quit() { + a.application.Shutdown() +} diff --git a/v2/init.go b/v2/pkg/application/init.go similarity index 51% rename from v2/init.go rename to v2/pkg/application/init.go index d6652f014..0fc48cb05 100644 --- a/v2/init.go +++ b/v2/pkg/application/init.go @@ -1,8 +1,8 @@ //go:build !windows // +build !windows -package wails +package application -func Init() error { +func applicationInit() error { return nil } diff --git a/v2/init_windows.go b/v2/pkg/application/init_windows.go similarity index 72% rename from v2/init_windows.go rename to v2/pkg/application/init_windows.go index 173da0a89..7d2900d3d 100644 --- a/v2/init_windows.go +++ b/v2/pkg/application/init_windows.go @@ -1,12 +1,13 @@ -package wails +//go:build windows + +package application import ( "fmt" "syscall" ) -// Init is called at the start of the application -func Init() error { +func applicationInit() error { status, r, err := syscall.NewLazyDLL("user32.dll").NewProc("SetProcessDPIAware").Call() if status == 0 { return fmt.Errorf("exit status %d: %v %v", status, r, err) diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 1f0a3532b..25f619b6b 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -47,9 +47,7 @@ type App struct { AlwaysOnTop bool // BackgroundColour is the background colour of the window // You can use the options.NewRGB and options.NewRGBA functions to create a new colour - BackgroundColour *RGBA - // RGBA is deprecated. Please use BackgroundColour - RGBA *RGBA + BackgroundColour *RGBA Assets fs.FS AssetsHandler http.Handler Menu *menu.Menu diff --git a/v2/wails.go b/v2/wails.go index 45334552a..54be64ca2 100644 --- a/v2/wails.go +++ b/v2/wails.go @@ -3,43 +3,13 @@ package wails import ( - "github.com/wailsapp/wails/v2/internal/app" _ "github.com/wailsapp/wails/v2/internal/goversion" // Add Compile-Time version check for minimum go version - "github.com/wailsapp/wails/v2/internal/signal" + "github.com/wailsapp/wails/v2/pkg/application" "github.com/wailsapp/wails/v2/pkg/options" ) -// This is the global application instance -var application *app.App - // Run creates an application based on the given config and executes it func Run(options *options.App) error { - - if options.RGBA != nil { - println("---- WARNING ----") - println("The `RGBA` option has been deprecated. Please use `BackgroundColour`.") - - if options.BackgroundColour == nil { - options.BackgroundColour = options.RGBA - } - } - - // Call an Init method manually - err := Init() - if err != nil { - return err - } - - application, err = app.CreateApp(options) - if err != nil { - return err - } - - signal.OnShutdown(func() { - application.Shutdown() - }) - - signal.Start() - - return application.Run() + mainApp := application.NewWithOptions(options) + return mainApp.Run() } From d319d51fcd6aa5f556fa92fde8e4c6727fb24235 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 26 Sep 2022 20:17:15 +1000 Subject: [PATCH 18/48] Refactor darwin app --- v2/internal/frontend/desktop/darwin/Application.h | 2 ++ v2/internal/frontend/desktop/darwin/Application.m | 8 ++++++++ v2/internal/frontend/desktop/darwin/frontend.go | 10 +++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index 8a657051b..86138dda1 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -77,6 +77,8 @@ void SetAbout(void *inctx, const char* title, const char* description, void* ima void* AppendMenuItem(void* inctx, void* nsmenu, const char* label, const char* shortcutKey, int modifiers, int disabled, int checked, int menuItemID); void AppendSeparator(void* inMenu); void UpdateMenuItem(void* nsmenuitem, int checked); +void RunMainLoop(void); +void ReleaseContext(void *inctx); NSString* safeInit(const char* input); diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index 43ba0545d..9ee3144ab 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -462,6 +462,14 @@ void Run(void *inctx, const char* url, int activationPolicy) { [_url release]; [app setMainMenu:ctx.applicationMenu]; +} + +void RunMainLoop(void) { + NSApplication *app = [NSApplication sharedApplication]; [app run]; +} + +void ReleaseContext(void *inctx) { + WailsContext *ctx = (__bridge WailsContext*) inctx; [ctx release]; } diff --git a/v2/internal/frontend/desktop/darwin/frontend.go b/v2/internal/frontend/desktop/darwin/frontend.go index 0bcad23bd..8fce1967c 100644 --- a/v2/internal/frontend/desktop/darwin/frontend.go +++ b/v2/internal/frontend/desktop/darwin/frontend.go @@ -74,6 +74,14 @@ type Frontend struct { trayMenusBuffer []*menu.TrayMenu } +func (f *Frontend) RunMainLoop() { + C.RunMainLoop() +} + +func (f *Frontend) WindowClose() { + C.ReleaseContext(f.mainWindow.context) +} + func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) *Frontend { result := &Frontend{ frontendOptions: appoptions, @@ -99,7 +107,7 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger. } else { appBindings.DB().UpdateObfuscatedCallMap() } - assets, err := assetserver.NewAssetServer(ctx, appoptions, bindings) + assets, err := assetserver.NewAssetServer(ctx, appoptions.Assets, appoptions.AssetsHandler, bindings) if err != nil { log.Fatal(err) } From 03dd51476820999ecbd8722ddc4b2af4cd757042 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 27 Sep 2022 17:51:19 +1000 Subject: [PATCH 19/48] Refactor app for linux --- v2/go.mod | 2 +- v2/internal/app/app_default_unix.go | 2 +- v2/internal/app/app_preflight_unix.go | 2 +- v2/internal/frontend/desktop/linux/frontend.go | 10 +++++++++- v2/internal/frontend/desktop/linux/window.go | 2 -- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/v2/go.mod b/v2/go.mod index eb538b381..b5533fcb9 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -1,6 +1,6 @@ module github.com/wailsapp/wails/v2 -go 1.19 +go 1.18 require ( github.com/Masterminds/semver v1.5.0 diff --git a/v2/internal/app/app_default_unix.go b/v2/internal/app/app_default_unix.go index 01a3225c7..10d801285 100644 --- a/v2/internal/app/app_default_unix.go +++ b/v2/internal/app/app_default_unix.go @@ -1,4 +1,4 @@ -//go:build !dev && !production && !bindings && darwin +//go:build !dev && !production && !bindings && (linux || darwin) package app diff --git a/v2/internal/app/app_preflight_unix.go b/v2/internal/app/app_preflight_unix.go index a135d7234..f554df740 100644 --- a/v2/internal/app/app_preflight_unix.go +++ b/v2/internal/app/app_preflight_unix.go @@ -1,4 +1,4 @@ -//go:build unix && !bindings +//go:build (linux || darwin) && !bindings package app diff --git a/v2/internal/frontend/desktop/linux/frontend.go b/v2/internal/frontend/desktop/linux/frontend.go index 64065a270..dce5b2531 100644 --- a/v2/internal/frontend/desktop/linux/frontend.go +++ b/v2/internal/frontend/desktop/linux/frontend.go @@ -52,6 +52,14 @@ type Frontend struct { dispatcher frontend.Dispatcher } +func (f *Frontend) RunMainLoop() { + C.gtk_main() +} + +func (f *Frontend) WindowClose() { + f.mainWindow.Destroy() +} + func init() { runtime.LockOSThread() } @@ -85,7 +93,7 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger. } else { appBindings.DB().UpdateObfuscatedCallMap() } - assets, err := assetserver.NewAssetServer(ctx, appoptions, bindings) + assets, err := assetserver.NewAssetServer(ctx, appoptions.Assets, appoptions.AssetsHandler, bindings) if err != nil { log.Fatal(err) } diff --git a/v2/internal/frontend/desktop/linux/window.go b/v2/internal/frontend/desktop/linux/window.go index a3ab6f85d..ef6ecafb6 100644 --- a/v2/internal/frontend/desktop/linux/window.go +++ b/v2/internal/frontend/desktop/linux/window.go @@ -861,8 +861,6 @@ func (w *Window) Run(url string) { w.Maximise() } - C.gtk_main() - w.Destroy() } func (w *Window) SetKeepAbove(top bool) { From bf088ea19c4137dd5347a82d1de07b72c84045f3 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 30 Sep 2022 08:09:37 +1000 Subject: [PATCH 20/48] Initial Windows systray support --- v2/internal/frontend/options/frontend.go | 9 + v2/internal/platform/systray.go | 25 ++ v2/internal/platform/systray/menu.go | 53 ++++ v2/internal/platform/systray/windows.go | 352 +++++++++++++++++++++++ v2/internal/platform/win32/consts.go | 155 ++++++++++ v2/internal/platform/win32/cursor.go | 9 + v2/internal/platform/win32/icon.go | 39 +++ v2/internal/platform/win32/menu.go | 29 ++ v2/internal/platform/win32/structs.go | 54 ++++ v2/internal/platform/win32/theme.go | 19 ++ v2/internal/platform/win32/window.go | 132 +++++++++ v2/internal/platform/win32/winres.go | 7 + v2/pkg/application/application.go | 39 ++- v2/pkg/application/events.go | 9 + v2/pkg/application/systray.go | 66 +++++ v2/pkg/menu/menuitem.go | 4 + v2/pkg/options/options.go | 9 + 17 files changed, 1009 insertions(+), 1 deletion(-) create mode 100644 v2/internal/frontend/options/frontend.go create mode 100644 v2/internal/platform/systray.go create mode 100644 v2/internal/platform/systray/menu.go create mode 100644 v2/internal/platform/systray/windows.go create mode 100644 v2/internal/platform/win32/consts.go create mode 100644 v2/internal/platform/win32/cursor.go create mode 100644 v2/internal/platform/win32/icon.go create mode 100644 v2/internal/platform/win32/menu.go create mode 100644 v2/internal/platform/win32/structs.go create mode 100644 v2/internal/platform/win32/theme.go create mode 100644 v2/internal/platform/win32/window.go create mode 100644 v2/internal/platform/win32/winres.go create mode 100644 v2/pkg/application/events.go create mode 100644 v2/pkg/application/systray.go diff --git a/v2/internal/frontend/options/frontend.go b/v2/internal/frontend/options/frontend.go new file mode 100644 index 000000000..aaab4459a --- /dev/null +++ b/v2/internal/frontend/options/frontend.go @@ -0,0 +1,9 @@ +package options + +import "github.com/wailsapp/wails/v2/pkg/options" + +// Frontend contains options for creating the Frontend +type Frontend struct { + options.App + HasMainWindow bool +} diff --git a/v2/internal/platform/systray.go b/v2/internal/platform/systray.go new file mode 100644 index 000000000..317ea7a7a --- /dev/null +++ b/v2/internal/platform/systray.go @@ -0,0 +1,25 @@ +package platform + +import ( + "github.com/wailsapp/wails/v2/internal/platform/systray" + "github.com/wailsapp/wails/v2/pkg/menu" +) +import "github.com/samber/lo" + +type SysTray interface { + // SetTitle sets the title of the tray menu + SetTitle(title string) + SetIcons(lightModeIcon []byte, darkModeIcon []byte) error + SetTooltip(tooltip string) error + Show() error + Hide() error + Run() error + Close() + AppendMenu(label string, callback menu.Callback) + AppendMenuItem(item *menu.MenuItem) + AppendSeparator() +} + +func NewSysTray() SysTray { + return lo.Must(systray.New()) +} diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go new file mode 100644 index 000000000..5bfa00da0 --- /dev/null +++ b/v2/internal/platform/systray/menu.go @@ -0,0 +1,53 @@ +package systray + +import ( + "errors" + "github.com/wailsapp/wails/v2/internal/platform/win32" + "github.com/wailsapp/wails/v2/pkg/menu" +) + +func displayMenu(hwnd win32.HWND, menuItems []*menu.MenuItem) error { + popupMenu := win32.CreatePopupMenu() + + for index, item := range menuItems { + var ret bool + itemID := win32.MenuItemMsgID + index + flags := win32.MF_STRING + if item.Disabled { + flags = flags | win32.MF_GRAYED + } + if item.Checked { + flags = flags | win32.MF_CHECKED + } + //if item.BarBreak { + // flags = flags | win32.MF_MENUBARBREAK + //} + if item.IsSeparator() { + flags = flags | win32.MF_SEPARATOR + } + + ret = win32.AppendMenu(popupMenu, uintptr(flags), uintptr(itemID), item.Label) + if ret == false { + return errors.New("AppendMenu failed") + } + } + + x, y, ok := win32.GetCursorPos() + if ok == false { + return errors.New("GetCursorPos failed") + } + + if win32.SetForegroundWindow(hwnd) == false { + return errors.New("SetForegroundWindow failed") + } + + if win32.TrackPopupMenu(popupMenu, win32.TPM_LEFTALIGN, x, y-5, hwnd) == false { + return errors.New("TrackPopupMenu failed") + } + + if win32.PostMessage(hwnd, win32.WM_NULL, 0, 0) == 0 { + return errors.New("PostMessage failed") + } + + return nil +} diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go new file mode 100644 index 000000000..fde7f3e3f --- /dev/null +++ b/v2/internal/platform/systray/windows.go @@ -0,0 +1,352 @@ +/* + * Based on code originally from https://github.com/tadvi/systray. Copyright (C) 2019 The Systray Authors. All Rights Reserved. + */ + +package systray + +import ( + "errors" + "github.com/wailsapp/wails/v2/internal/platform/win32" + "github.com/wailsapp/wails/v2/pkg/menu" + "golang.org/x/sys/windows" + "syscall" + "unsafe" +) + +var ( + user32 = syscall.MustLoadDLL("user32.dll") + + DefWindowProc = user32.MustFindProc("DefWindowProcW") + RegisterClassEx = user32.MustFindProc("RegisterClassExW") + CreateWindowEx = user32.MustFindProc("CreateWindowExW") +) + +type Systray struct { + id uint32 + hwnd win32.HWND + hinst win32.HINSTANCE + lclick func() + rclick func() + lightModeIcon win32.HICON + darkModeIcon win32.HICON + + Menu []*menu.MenuItem + + quit chan struct{} +} + +func (p *Systray) Close() { + err := p.Stop() + if err != nil { + println(err.Error()) + } +} + +// SetTitle is unused on Windows +func (p *Systray) SetTitle(_ string) {} + +func New() (*Systray, error) { + ni := &Systray{lclick: func() {}, rclick: func() {}} + + MainClassName := "WailsSystray" + ni.hinst, _ = RegisterWindow(MainClassName, ni.WinProc) + + mhwnd := win32.CreateWindowEx( + win32.WS_EX_CONTROLPARENT, + win32.MustStringToUTF16Ptr(MainClassName), + win32.MustStringToUTF16Ptr(""), + win32.WS_OVERLAPPEDWINDOW|win32.WS_CLIPSIBLINGS, + win32.CW_USEDEFAULT, + win32.CW_USEDEFAULT, + win32.CW_USEDEFAULT, + win32.CW_USEDEFAULT, + 0, + 0, + 0, + unsafe.Pointer(nil)) + + if mhwnd == 0 { + return nil, errors.New("create main win failed") + } + + NotifyIconClassName := "NotifyIconForm" + _, err := RegisterWindow(NotifyIconClassName, ni.WinProc) + if err != nil { + return nil, err + } + + hwnd, _, _ := CreateWindowEx.Call( + 0, + uintptr(unsafe.Pointer(win32.MustStringToUTF16Ptr(NotifyIconClassName))), + 0, + 0, + 0, + 0, + 0, + 0, + uintptr(win32.HWND_MESSAGE), + 0, + 0, + 0) + if hwnd == 0 { + return nil, errors.New("create notify win failed") + } + + ni.hwnd = win32.HWND(hwnd) // Important to keep this inside struct. + + nid := win32.NOTIFYICONDATA{ + HWnd: win32.HWND(hwnd), + UFlags: win32.NIF_MESSAGE | win32.NIF_STATE, + DwState: win32.NIS_HIDDEN, + DwStateMask: win32.NIS_HIDDEN, + UCallbackMessage: win32.NotifyIconMessageId, + } + nid.CbSize = uint32(unsafe.Sizeof(nid)) + + ret := win32.ShellNotifyIcon(win32.NIM_ADD, &nid) + if ret == 0 { + return nil, errors.New("shell notify create failed") + } + + nid.UVersion = win32.NOTIFYICON_VERSION + + ret = win32.ShellNotifyIcon(win32.NIM_SETVERSION, &nid) + if ret == 0 { + return nil, errors.New("shell notify version failed") + } + + ni.id = nid.UID + return ni, nil +} + +func (p *Systray) HWND() win32.HWND { + return p.hwnd +} + +// AppendMenu add menu item. +func (p *Systray) AppendMenu(label string, onclick menu.Callback) { + p.Menu = append(p.Menu, &menu.MenuItem{Type: menu.TextType, Label: label, Click: onclick}) +} + +// AppendMenuItem add menu item. +func (p *Systray) AppendMenuItem(item *menu.MenuItem) { + p.Menu = append(p.Menu, item) +} + +// AppendSeparator to the menu. +func (p *Systray) AppendSeparator() { + p.Menu = append(p.Menu, menu.Separator()) +} + +func (p *Systray) Stop() error { + nid := p.newNotifyIconData() + ret := win32.ShellNotifyIcon(win32.NIM_DELETE, &nid) + if ret == 0 { + return errors.New("shell notify delete failed") + } + return nil +} + +func (p *Systray) Click(fn func()) { + p.lclick = fn +} + +func (p *Systray) OnRightClick(fn func()) { + p.rclick = fn +} + +func (p *Systray) SetTooltip(tooltip string) error { + nid := p.newNotifyIconData() + nid.UFlags = win32.NIF_TIP + copy(nid.SzTip[:], win32.MustUTF16FromString(tooltip)) + + ret := win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) + if ret == 0 { + return errors.New("shell notify tooltip failed") + } + return nil +} + +func (p *Systray) ShowMessage(title, msg string, bigIcon bool) error { + nid := p.newNotifyIconData() + if bigIcon == true { + nid.DwInfoFlags = win32.NIIF_USER + } + + nid.CbSize = uint32(unsafe.Sizeof(nid)) + + nid.UFlags = win32.NIF_INFO + copy(nid.SzInfoTitle[:], win32.MustUTF16FromString(title)) + copy(nid.SzInfo[:], win32.MustUTF16FromString(msg)) + + ret := win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) + if ret == 0 { + return errors.New("shell notify tooltip failed") + } + return nil +} + +func (p *Systray) newNotifyIconData() win32.NOTIFYICONDATA { + nid := win32.NOTIFYICONDATA{ + UID: p.id, + HWnd: p.hwnd, + } + nid.CbSize = uint32(unsafe.Sizeof(nid)) + return nid +} + +func (p *Systray) Show() error { + return p.setVisible(true) +} + +func (p *Systray) Hide() error { + return p.setVisible(false) +} + +func (p *Systray) setVisible(visible bool) error { + nid := p.newNotifyIconData() + nid.UFlags = win32.NIF_STATE + nid.DwStateMask = win32.NIS_HIDDEN + if !visible { + nid.DwState = win32.NIS_HIDDEN + } + + ret := win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) + if ret == 0 { + return errors.New("shell notify tooltip failed") + } + return nil +} + +func (p *Systray) SetIcons(lightModeIcon []byte, darkModeIcon []byte) error { + p.lightModeIcon = p.getIcon(lightModeIcon) + p.darkModeIcon = p.getIcon(darkModeIcon) + return p.updateIcon() +} + +func (p *Systray) getIcon(icon []byte) win32.HICON { + result, err := win32.CreateHIconFromPNG(icon) + if err != nil { + result = win32.LoadIconWithResourceID(0, uintptr(win32.IDI_APPLICATION)) + } + return result +} + +func (p *Systray) setIcon(hicon win32.HICON) error { + nid := p.newNotifyIconData() + nid.UFlags = win32.NIF_ICON + if hicon == 0 { + nid.HIcon = 0 + } else { + nid.HIcon = hicon + } + + ret := win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) + if ret == 0 { + return errors.New("shell notify icon failed") + } + return nil +} + +func (p *Systray) WinProc(hwnd win32.HWND, msg uint32, wparam, lparam uintptr) uintptr { + switch msg { + case win32.NotifyIconMessageId: + if lparam == win32.WM_LBUTTONUP { + p.lclick() + if len(p.Menu) > 0 { + err := displayMenu(p.hwnd, p.Menu) + if err != nil { + return 0 + } + } + } else if lparam == win32.WM_RBUTTONUP { + p.rclick() + if len(p.Menu) > 0 { + err := displayMenu(p.hwnd, p.Menu) + if err != nil { + return 0 + } + } + } + case win32.WM_SETTINGCHANGE: + settingChanged := windows.UTF16PtrToString((*uint16)(unsafe.Pointer(lparam))) + if settingChanged == "ImmersiveColorSet" { + err := p.updateIcon() + if err != nil { + println("update icon failed", err.Error()) + } + } + return 0 + case win32.WM_COMMAND: + cmdMsgID := int(wparam & 0xffff) + switch cmdMsgID { + default: + if cmdMsgID >= win32.MenuItemMsgID && cmdMsgID < (win32.MenuItemMsgID+len(p.Menu)) { + itemIndex := cmdMsgID - win32.MenuItemMsgID + menuItem := p.Menu[itemIndex] + menuItem.Click(nil) + } + } + } + + result, _, _ := DefWindowProc.Call(uintptr(hwnd), uintptr(msg), wparam, lparam) + return result +} + +func (p *Systray) Run() error { + var msg win32.MSG + for { + rt := win32.GetMessage(&msg) + switch int(rt) { + case 0: + println("Quitting Run()") + return nil + case -1: + return errors.New("run failed") + } + + if win32.IsDialogMessage(p.hwnd, &msg) == 0 { + win32.TranslateMessage(&msg) + win32.DispatchMessage(&msg) + } + } +} + +func (p *Systray) updateIcon() error { + if win32.IsCurrentlyDarkMode() { + return p.setIcon(p.darkModeIcon) + } + return p.setIcon(p.lightModeIcon) +} + +func RegisterWindow(name string, proc win32.WindowProc) (win32.HINSTANCE, error) { + hinst := win32.GetModuleHandle(0) + if hinst == 0 { + return 0, errors.New("get module handle failed") + } + hicon := win32.LoadIconWithResourceID(0, uintptr(win32.IDI_APPLICATION)) + if hicon == 0 { + return 0, errors.New("load icon failed") + } + hcursor := win32.LoadCursorWithResourceID(0, uintptr(win32.IDC_ARROW)) + if hcursor == 0 { + return 0, errors.New("load cursor failed") + } + + hi := win32.HINSTANCE(hinst) + + var wc win32.WNDCLASSEX + wc.CbSize = uint32(unsafe.Sizeof(wc)) + wc.LpfnWndProc = syscall.NewCallback(proc) + wc.HInstance = win32.HINSTANCE(hinst) + wc.HIcon = hicon + wc.HCursor = hcursor + wc.HbrBackground = win32.COLOR_BTNFACE + 1 + wc.LpszClassName = win32.MustStringToUTF16Ptr(name) + + atom, _, _ := RegisterClassEx.Call(uintptr(unsafe.Pointer(&wc))) + if atom == 0 { + return 0, errors.New("register class failed") + } + return hi, nil +} diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go new file mode 100644 index 000000000..dca347d98 --- /dev/null +++ b/v2/internal/platform/win32/consts.go @@ -0,0 +1,155 @@ +package win32 + +import ( + "syscall" + "unsafe" +) + +var ( + modKernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetModuleHandle = modKernel32.NewProc("GetModuleHandleW") + + moduser32 = syscall.NewLazyDLL("user32.dll") + procRegisterClassEx = moduser32.NewProc("RegisterClassExW") + procLoadIcon = moduser32.NewProc("LoadIconW") + procLoadCursor = moduser32.NewProc("LoadCursorW") + procCreateWindowEx = moduser32.NewProc("CreateWindowExW") + procPostMessage = moduser32.NewProc("PostMessageW") + procGetCursorPos = moduser32.NewProc("GetCursorPos") + procSetForegroundWindow = moduser32.NewProc("SetForegroundWindow") + procCreatePopupMenu = moduser32.NewProc("CreatePopupMenu") + procTrackPopupMenu = moduser32.NewProc("TrackPopupMenu") + procAppendMenuW = moduser32.NewProc("AppendMenuW") + procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx") + procGetMessageW = moduser32.NewProc("GetMessageW") + procIsDialogMessage = moduser32.NewProc("IsDialogMessageW") + procTranslateMessage = moduser32.NewProc("TranslateMessage") + procDispatchMessage = moduser32.NewProc("DispatchMessageW") + + modshell32 = syscall.NewLazyDLL("shell32.dll") + procShellNotifyIcon = modshell32.NewProc("Shell_NotifyIconW") +) + +type HANDLE uintptr +type HINSTANCE HANDLE +type HICON HANDLE +type HCURSOR HANDLE +type HBRUSH HANDLE +type HWND HANDLE +type HMENU HANDLE +type ATOM uint16 + +const ( + WM_LBUTTONUP = 0x0202 + WM_LBUTTONDBLCLK = 0x0203 + WM_RBUTTONUP = 0x0205 + WM_USER = 0x0400 + WM_TRAYICON = WM_USER + 69 + WM_SETTINGCHANGE = 0x001A + + WS_EX_APPWINDOW = 0x00040000 + WS_OVERLAPPEDWINDOW = 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000 + CW_USEDEFAULT = 0x80000000 + + NIM_ADD = 0x00000000 + NIM_MODIFY = 0x00000001 + NIM_DELETE = 0x00000002 + NIM_SETVERSION = 0x00000004 + + NIF_MESSAGE = 0x00000001 + NIF_ICON = 0x00000002 + NIF_TIP = 0x00000004 + NIF_STATE = 0x00000008 + NIF_INFO = 0x00000010 + + NIS_HIDDEN = 0x00000001 + + NIIF_NONE = 0x00000000 + NIIF_INFO = 0x00000001 + NIIF_WARNING = 0x00000002 + NIIF_ERROR = 0x00000003 + NIIF_USER = 0x00000004 + NIIF_NOSOUND = 0x00000010 + NIIF_LARGE_ICON = 0x00000020 + NIIF_RESPECT_QUIET_TIME = 0x00000080 + NIIF_ICON_MASK = 0x0000000F + + IMAGE_BITMAP = 0 + IMAGE_ICON = 1 + LR_LOADFROMFILE = 0x00000010 + LR_DEFAULTSIZE = 0x00000040 + + IDC_ARROW = 32512 + COLOR_WINDOW = 5 + COLOR_BTNFACE = 15 + + GWLP_USERDATA = -21 + WS_CLIPSIBLINGS = 0x04000000 + WS_EX_CONTROLPARENT = 0x00010000 + + HWND_MESSAGE = ^HWND(2) + NOTIFYICON_VERSION = 4 + + IDI_APPLICATION = 32512 + WM_APP = 32768 + WM_COMMAND = 273 + + MenuItemMsgID = WM_APP + 1024 + NotifyIconMessageId = WM_APP + iota + + MF_STRING = 0x00000000 + MF_ENABLED = 0x00000000 + MF_GRAYED = 0x00000001 + MF_DISABLED = 0x00000002 + MF_SEPARATOR = 0x00000800 + MF_CHECKED = 0x00000008 + MF_MENUBARBREAK = 0x00000020 + + TPM_LEFTALIGN = 0x0000 + WM_NULL = 0 + + CS_VREDRAW = 0x0001 + CS_HREDRAW = 0x0002 +) + +type WindowProc func(hwnd HWND, msg uint32, wparam, lparam uintptr) uintptr + +func GetModuleHandle(value uintptr) uintptr { + result, _, _ := procGetModuleHandle.Call(value) + return result +} + +func GetMessage(msg *MSG) uintptr { + rt, _, _ := procGetMessageW.Call(uintptr(unsafe.Pointer(&msg)), 0, 0, 0) + return rt +} + +func PostMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { + ret, _, _ := procPostMessage.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam) + + return ret +} + +func ShellNotifyIcon(cmd uintptr, nid *NOTIFYICONDATA) uintptr { + ret, _, _ := procShellNotifyIcon.Call(cmd, uintptr(unsafe.Pointer(nid))) + return ret +} + +func IsDialogMessage(hwnd HWND, msg *MSG) uintptr { + ret, _, _ := procIsDialogMessage.Call(uintptr(hwnd), uintptr(unsafe.Pointer(msg))) + return ret +} + +func TranslateMessage(msg *MSG) uintptr { + ret, _, _ := procTranslateMessage.Call(uintptr(unsafe.Pointer(msg))) + return ret +} + +func DispatchMessage(msg *MSG) uintptr { + ret, _, _ := procDispatchMessage.Call(uintptr(unsafe.Pointer(msg))) + return ret +} diff --git a/v2/internal/platform/win32/cursor.go b/v2/internal/platform/win32/cursor.go new file mode 100644 index 000000000..a9a32e733 --- /dev/null +++ b/v2/internal/platform/win32/cursor.go @@ -0,0 +1,9 @@ +package win32 + +import "unsafe" + +func GetCursorPos() (x, y int, ok bool) { + pt := POINT{} + ret, _, _ := procGetCursorPos.Call(uintptr(unsafe.Pointer(&pt))) + return int(pt.X), int(pt.Y), ret != 0 +} diff --git a/v2/internal/platform/win32/icon.go b/v2/internal/platform/win32/icon.go new file mode 100644 index 000000000..43eb9a4a1 --- /dev/null +++ b/v2/internal/platform/win32/icon.go @@ -0,0 +1,39 @@ +package win32 + +import ( + "unsafe" +) + +func CreateIconFromResourceEx(presbits uintptr, dwResSize uint32, isIcon bool, version uint32, cxDesired int, cyDesired int, flags uint) (uintptr, error) { + icon := 0 + if isIcon { + icon = 1 + } + r, _, err := procCreateIconFromResourceEx.Call( + presbits, + uintptr(dwResSize), + uintptr(icon), + uintptr(version), + uintptr(cxDesired), + uintptr(cyDesired), + uintptr(flags), + ) + + if r == 0 { + return 0, err + } + return r, nil +} + +// CreateHIconFromPNG creates a HICON from a PNG file +func CreateHIconFromPNG(pngData []byte) (HICON, error) { + icon, err := CreateIconFromResourceEx( + uintptr(unsafe.Pointer(&pngData[0])), + uint32(len(pngData)), + true, + 0x00030000, + 0, + 0, + LR_DEFAULTSIZE) + return HICON(icon), err +} diff --git a/v2/internal/platform/win32/menu.go b/v2/internal/platform/win32/menu.go new file mode 100644 index 000000000..332e859e7 --- /dev/null +++ b/v2/internal/platform/win32/menu.go @@ -0,0 +1,29 @@ +package win32 + +func CreatePopupMenu() HMENU { + ret, _, _ := procCreatePopupMenu.Call(0, 0, 0, 0) + return HMENU(ret) +} + +func TrackPopupMenu(menu HMENU, flags uint, x, y int, wnd HWND) bool { + ret, _, _ := procTrackPopupMenu.Call( + uintptr(menu), + uintptr(flags), + uintptr(x), + uintptr(y), + 0, + uintptr(wnd), + 0, + ) + return ret != 0 +} + +func AppendMenu(menu HMENU, flags uintptr, id uintptr, text string) bool { + ret, _, _ := procAppendMenuW.Call( + uintptr(menu), + flags, + id, + MustStringToUTF16uintptr(text), + ) + return ret != 0 +} diff --git a/v2/internal/platform/win32/structs.go b/v2/internal/platform/win32/structs.go new file mode 100644 index 000000000..a0772d004 --- /dev/null +++ b/v2/internal/platform/win32/structs.go @@ -0,0 +1,54 @@ +package win32 + +type NOTIFYICONDATA struct { + CbSize uint32 + HWnd HWND + UID uint32 + UFlags uint32 + UCallbackMessage uint32 + HIcon HICON + SzTip [128]uint16 + DwState uint32 + DwStateMask uint32 + SzInfo [256]uint16 + UVersion uint32 + SzInfoTitle [64]uint16 + DwInfoFlags uint32 + GuidItem GUID + HBalloonIcon HICON +} + +type GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]byte +} + +type WNDCLASSEX struct { + CbSize uint32 + Style uint32 + LpfnWndProc uintptr + CbClsExtra int32 + CbWndExtra int32 + HInstance HINSTANCE + HIcon HICON + HCursor HCURSOR + HbrBackground HBRUSH + LpszMenuName *uint16 + LpszClassName *uint16 + HIconSm HICON +} + +type MSG struct { + HWnd HWND + Message uint32 + WParam uintptr + LParam uintptr + Time uint32 + Pt POINT +} + +type POINT struct { + X, Y int32 +} diff --git a/v2/internal/platform/win32/theme.go b/v2/internal/platform/win32/theme.go new file mode 100644 index 000000000..d5a23eca4 --- /dev/null +++ b/v2/internal/platform/win32/theme.go @@ -0,0 +1,19 @@ +package win32 + +import ( + "golang.org/x/sys/windows/registry" +) + +func IsCurrentlyDarkMode() bool { + key, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.QUERY_VALUE) + if err != nil { + return false + } + defer key.Close() + + AppsUseLightTheme, _, err := key.GetIntegerValue("AppsUseLightTheme") + if err != nil { + return false + } + return AppsUseLightTheme == 0 +} diff --git a/v2/internal/platform/win32/window.go b/v2/internal/platform/win32/window.go new file mode 100644 index 000000000..62546ff23 --- /dev/null +++ b/v2/internal/platform/win32/window.go @@ -0,0 +1,132 @@ +package win32 + +import ( + "fmt" + "github.com/samber/lo" + "syscall" + "unsafe" +) + +func LoadIconWithResourceID(instance HINSTANCE, res uintptr) HICON { + ret, _, _ := procLoadIcon.Call( + uintptr(instance), + res) + + return HICON(ret) +} + +func LoadCursorWithResourceID(instance HINSTANCE, res uintptr) HCURSOR { + ret, _, _ := procLoadCursor.Call( + uintptr(instance), + res) + + return HCURSOR(ret) +} + +func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM { + ret, _, _ := procRegisterClassEx.Call(uintptr(unsafe.Pointer(wndClassEx))) + return ATOM(ret) +} + +func RegisterClass(className string, wndproc uintptr, instance HINSTANCE) error { + classNamePtr, err := syscall.UTF16PtrFromString(className) + if err != nil { + return err + } + icon := LoadIconWithResourceID(instance, IDI_APPLICATION) + + var wc WNDCLASSEX + wc.CbSize = uint32(unsafe.Sizeof(wc)) + wc.Style = CS_HREDRAW | CS_VREDRAW + wc.LpfnWndProc = wndproc + wc.HInstance = instance + wc.HbrBackground = COLOR_WINDOW + 1 + wc.HIcon = icon + wc.HCursor = LoadCursorWithResourceID(0, IDC_ARROW) + wc.LpszClassName = classNamePtr + wc.LpszMenuName = nil + wc.HIconSm = icon + + if ret := RegisterClassEx(&wc); ret == 0 { + return syscall.GetLastError() + } + + return nil +} + +func CreateWindow(className string, instance HINSTANCE, parent HWND, exStyle, style uint) HWND { + + classNamePtr := lo.Must(syscall.UTF16PtrFromString(className)) + + result := CreateWindowEx( + exStyle, + classNamePtr, + nil, + style, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + parent, + 0, + instance, + nil) + + if result == 0 { + errStr := fmt.Sprintf("Error occurred in CreateWindow(%s, %v, %d, %d)", className, parent, exStyle, style) + panic(errStr) + } + + return result +} + +func CreateWindowEx(exStyle uint, className, windowName *uint16, + style uint, x, y, width, height int, parent HWND, menu HMENU, + instance HINSTANCE, param unsafe.Pointer) HWND { + ret, _, _ := procCreateWindowEx.Call( + uintptr(exStyle), + uintptr(unsafe.Pointer(className)), + uintptr(unsafe.Pointer(windowName)), + uintptr(style), + uintptr(x), + uintptr(y), + uintptr(width), + uintptr(height), + uintptr(parent), + uintptr(menu), + uintptr(instance), + uintptr(param)) + + return HWND(ret) +} + +func MustStringToUTF16Ptr(input string) *uint16 { + ret, err := syscall.UTF16PtrFromString(input) + if err != nil { + panic(err) + } + return ret +} + +func MustStringToUTF16uintptr(input string) uintptr { + ret, err := syscall.UTF16PtrFromString(input) + if err != nil { + panic(err) + } + return uintptr(unsafe.Pointer(ret)) +} + +func MustUTF16FromString(input string) []uint16 { + ret, err := syscall.UTF16FromString(input) + if err != nil { + panic(err) + } + return ret +} + +func SetForegroundWindow(wnd HWND) bool { + ret, _, _ := procSetForegroundWindow.Call( + uintptr(wnd), + ) + return ret != 0 +} diff --git a/v2/internal/platform/win32/winres.go b/v2/internal/platform/win32/winres.go new file mode 100644 index 000000000..3a51068a9 --- /dev/null +++ b/v2/internal/platform/win32/winres.go @@ -0,0 +1,7 @@ +package win32 + +import "unsafe" + +func MakeIntResource(id uint16) *uint16 { + return (*uint16)(unsafe.Pointer(uintptr(id))) +} diff --git a/v2/pkg/application/application.go b/v2/pkg/application/application.go index 205ef6bfb..2694ce09e 100644 --- a/v2/pkg/application/application.go +++ b/v2/pkg/application/application.go @@ -1,6 +1,7 @@ package application import ( + "context" "github.com/wailsapp/wails/v2/internal/app" "github.com/wailsapp/wails/v2/internal/signal" "github.com/wailsapp/wails/v2/pkg/menu" @@ -12,6 +13,9 @@ type Application struct { application *app.App options *options.App + // System Trays + systemTrays []*SystemTray + // running flag running bool } @@ -66,10 +70,43 @@ func (a *Application) Run() error { a.running = true - return a.application.Run() + err = a.application.Run() + a.Quit() + return err } // Quit will shut down the application func (a *Application) Quit() { + for _, systray := range a.systemTrays { + systray.Close() + } a.application.Shutdown() } + +// Bind the given struct to the application +func (a *Application) Bind(boundStruct any) { + a.options.Bind = append(a.options.Bind, boundStruct) +} + +func (a *Application) On(eventType EventType, callback func()) { + + c := func(ctx context.Context) { + callback() + } + + switch eventType { + case StartUp: + a.options.OnStartup = c + case ShutDown: + a.options.OnShutdown = c + case DomReady: + a.options.OnDomReady = c + } +} + +func (a *Application) NewSystemTray(options *options.SystemTray) *SystemTray { + systemTray := newSystemTray(options) + a.systemTrays = append(a.systemTrays, systemTray) + println("created systemTray") + return systemTray +} diff --git a/v2/pkg/application/events.go b/v2/pkg/application/events.go new file mode 100644 index 000000000..3896e9e75 --- /dev/null +++ b/v2/pkg/application/events.go @@ -0,0 +1,9 @@ +package application + +type EventType int + +const ( + StartUp EventType = iota + ShutDown + DomReady +) diff --git a/v2/pkg/application/systray.go b/v2/pkg/application/systray.go new file mode 100644 index 000000000..74535b676 --- /dev/null +++ b/v2/pkg/application/systray.go @@ -0,0 +1,66 @@ +package application + +import ( + "github.com/wailsapp/wails/v2/internal/platform" + "github.com/wailsapp/wails/v2/pkg/menu" + "github.com/wailsapp/wails/v2/pkg/options" +) + +// SystemTray defines a system tray! +type SystemTray struct { + title string + hidden bool + lightModeIcon []byte + darkModeIcon []byte + tooltip string + startHidden bool + + // The platform specific implementation + impl platform.SysTray +} + +func newSystemTray(options *options.SystemTray) *SystemTray { + return &SystemTray{ + impl: platform.NewSysTray(), + title: options.Title, + lightModeIcon: options.LightModeIcon, + darkModeIcon: options.DarkModeIcon, + tooltip: options.Tooltip, + startHidden: options.StartHidden, + } +} + +func (t *SystemTray) run() { + t.impl.SetTitle(t.title) + t.impl.SetIcons(t.lightModeIcon, t.darkModeIcon) + t.impl.SetTooltip(t.tooltip) + if !t.startHidden { + t.impl.Show() + } + t.impl.Run() +} + +func (t *SystemTray) SetTitle(title string) { + t.title = title + t.impl.SetTitle(title) +} +func (t *SystemTray) AppendMenu(label string, callback menu.Callback) { + t.impl.AppendMenu(label, callback) +} + +func (t *SystemTray) Run() error { + t.run() + return nil +} + +func (t *SystemTray) Close() { + t.impl.Close() +} + +func (t *SystemTray) AppendSeperator() { + t.impl.AppendSeparator() +} + +func (t *SystemTray) AppendMenuItem(item *menu.MenuItem) { + t.impl.AppendMenuItem(item) +} diff --git a/v2/pkg/menu/menuitem.go b/v2/pkg/menu/menuitem.go index f5b34dff2..ac5ebd7be 100644 --- a/v2/pkg/menu/menuitem.go +++ b/v2/pkg/menu/menuitem.go @@ -239,6 +239,10 @@ func (m *MenuItem) SetLabel(name string) { m.Impl.SetLabel(name) } +func (m *MenuItem) IsSeparator() bool { + return m.Type == SeparatorType +} + // Text is a helper to create basic Text menu items func Text(label string, accelerator *keys.Accelerator, click Callback) *MenuItem { return &MenuItem{ diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 25f619b6b..98d36d2c8 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -170,3 +170,12 @@ func processDragOptions(appoptions *App) { appoptions.CSSDragProperty = html.EscapeString(appoptions.CSSDragProperty) appoptions.CSSDragValue = html.EscapeString(appoptions.CSSDragValue) } + +// SystemTray contains options for the system tray +type SystemTray struct { + LightModeIcon []byte + DarkModeIcon []byte + Title string + Tooltip string + StartHidden bool +} From a967ce0a290af075f9e4b9eb4401da74d3bc4036 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 4 Oct 2022 20:17:46 +1100 Subject: [PATCH 21/48] Refactor light/dark icons --- v2/internal/platform/systray.go | 3 +- v2/internal/platform/systray/windows.go | 49 ++++++++++++++++++------- v2/internal/platform/win32/window.go | 5 +++ v2/pkg/application/systray.go | 4 +- v2/pkg/options/options.go | 9 ----- v2/pkg/options/systemtray.go | 15 ++++++++ 6 files changed, 60 insertions(+), 25 deletions(-) create mode 100644 v2/pkg/options/systemtray.go diff --git a/v2/internal/platform/systray.go b/v2/internal/platform/systray.go index 317ea7a7a..2f047249c 100644 --- a/v2/internal/platform/systray.go +++ b/v2/internal/platform/systray.go @@ -3,13 +3,13 @@ package platform import ( "github.com/wailsapp/wails/v2/internal/platform/systray" "github.com/wailsapp/wails/v2/pkg/menu" + "github.com/wailsapp/wails/v2/pkg/options" ) import "github.com/samber/lo" type SysTray interface { // SetTitle sets the title of the tray menu SetTitle(title string) - SetIcons(lightModeIcon []byte, darkModeIcon []byte) error SetTooltip(tooltip string) error Show() error Hide() error @@ -18,6 +18,7 @@ type SysTray interface { AppendMenu(label string, callback menu.Callback) AppendMenuItem(item *menu.MenuItem) AppendSeparator() + SetIcons(lightModeIcon, darkModeIcon *options.SystemTrayIcon) error } func NewSysTray() SysTray { diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go index fde7f3e3f..27ff447e1 100644 --- a/v2/internal/platform/systray/windows.go +++ b/v2/internal/platform/systray/windows.go @@ -6,9 +6,10 @@ package systray import ( "errors" + "github.com/samber/lo" "github.com/wailsapp/wails/v2/internal/platform/win32" "github.com/wailsapp/wails/v2/pkg/menu" - "golang.org/x/sys/windows" + "github.com/wailsapp/wails/v2/pkg/options" "syscall" "unsafe" ) @@ -22,17 +23,21 @@ var ( ) type Systray struct { - id uint32 - hwnd win32.HWND - hinst win32.HINSTANCE - lclick func() - rclick func() + id uint32 + hwnd win32.HWND + hinst win32.HINSTANCE + lclick func() + rclick func() + + appIcon win32.HICON lightModeIcon win32.HICON darkModeIcon win32.HICON + currentIcon win32.HICON Menu []*menu.MenuItem quit chan struct{} + icon *options.SystemTrayIcon } func (p *Systray) Close() { @@ -115,6 +120,9 @@ func New() (*Systray, error) { return nil, errors.New("shell notify version failed") } + ni.appIcon = win32.LoadIconWithResourceID(0, uintptr(win32.IDI_APPLICATION)) + ni.lightModeIcon = ni.appIcon + ni.darkModeIcon = ni.appIcon ni.id = nid.UID return ni, nil } @@ -218,16 +226,23 @@ func (p *Systray) setVisible(visible bool) error { return nil } -func (p *Systray) SetIcons(lightModeIcon []byte, darkModeIcon []byte) error { - p.lightModeIcon = p.getIcon(lightModeIcon) - p.darkModeIcon = p.getIcon(darkModeIcon) +func (p *Systray) SetIcons(lightModeIcon, darkModeIcon *options.SystemTrayIcon) error { + var newLightModeIcon, newDarkModeIcon win32.HICON + if lightModeIcon != nil && lightModeIcon.Data != nil { + newLightModeIcon = p.getIcon(lightModeIcon.Data) + } + if darkModeIcon != nil && darkModeIcon.Data != nil { + newDarkModeIcon = p.getIcon(darkModeIcon.Data) + } + p.lightModeIcon, _ = lo.Coalesce(newLightModeIcon, newDarkModeIcon, p.appIcon) + p.darkModeIcon, _ = lo.Coalesce(newDarkModeIcon, newLightModeIcon, p.appIcon) return p.updateIcon() } func (p *Systray) getIcon(icon []byte) win32.HICON { result, err := win32.CreateHIconFromPNG(icon) if err != nil { - result = win32.LoadIconWithResourceID(0, uintptr(win32.IDI_APPLICATION)) + result = p.appIcon } return result } @@ -269,7 +284,7 @@ func (p *Systray) WinProc(hwnd win32.HWND, msg uint32, wparam, lparam uintptr) u } } case win32.WM_SETTINGCHANGE: - settingChanged := windows.UTF16PtrToString((*uint16)(unsafe.Pointer(lparam))) + settingChanged := win32.UTF16PtrToString(lparam) if settingChanged == "ImmersiveColorSet" { err := p.updateIcon() if err != nil { @@ -313,10 +328,18 @@ func (p *Systray) Run() error { } func (p *Systray) updateIcon() error { + + var newIcon win32.HICON if win32.IsCurrentlyDarkMode() { - return p.setIcon(p.darkModeIcon) + newIcon = p.darkModeIcon + } else { + newIcon = p.lightModeIcon } - return p.setIcon(p.lightModeIcon) + if p.currentIcon == newIcon { + return nil + } + p.currentIcon = newIcon + return p.setIcon(newIcon) } func RegisterWindow(name string, proc win32.WindowProc) (win32.HINSTANCE, error) { diff --git a/v2/internal/platform/win32/window.go b/v2/internal/platform/win32/window.go index 62546ff23..7cf15cadb 100644 --- a/v2/internal/platform/win32/window.go +++ b/v2/internal/platform/win32/window.go @@ -3,6 +3,7 @@ package win32 import ( "fmt" "github.com/samber/lo" + "golang.org/x/sys/windows" "syscall" "unsafe" ) @@ -124,6 +125,10 @@ func MustUTF16FromString(input string) []uint16 { return ret } +func UTF16PtrToString(input uintptr) string { + return windows.UTF16PtrToString((*uint16)(unsafe.Pointer(input))) +} + func SetForegroundWindow(wnd HWND) bool { ret, _, _ := procSetForegroundWindow.Call( uintptr(wnd), diff --git a/v2/pkg/application/systray.go b/v2/pkg/application/systray.go index 74535b676..58cfdd34a 100644 --- a/v2/pkg/application/systray.go +++ b/v2/pkg/application/systray.go @@ -10,8 +10,8 @@ import ( type SystemTray struct { title string hidden bool - lightModeIcon []byte - darkModeIcon []byte + lightModeIcon *options.SystemTrayIcon + darkModeIcon *options.SystemTrayIcon tooltip string startHidden bool diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 98d36d2c8..25f619b6b 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -170,12 +170,3 @@ func processDragOptions(appoptions *App) { appoptions.CSSDragProperty = html.EscapeString(appoptions.CSSDragProperty) appoptions.CSSDragValue = html.EscapeString(appoptions.CSSDragValue) } - -// SystemTray contains options for the system tray -type SystemTray struct { - LightModeIcon []byte - DarkModeIcon []byte - Title string - Tooltip string - StartHidden bool -} diff --git a/v2/pkg/options/systemtray.go b/v2/pkg/options/systemtray.go new file mode 100644 index 000000000..51463c534 --- /dev/null +++ b/v2/pkg/options/systemtray.go @@ -0,0 +1,15 @@ +package options + +// SystemTray contains options for the system tray +type SystemTray struct { + LightModeIcon *SystemTrayIcon + DarkModeIcon *SystemTrayIcon + Title string + Tooltip string + StartHidden bool +} + +// SystemTrayIcon represents a system tray icon +type SystemTrayIcon struct { + Data []byte +} From c63f8160a69ef88bf8067826831c75f9b44ce105 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Wed, 5 Oct 2022 07:15:36 +1100 Subject: [PATCH 22/48] Move systray startup into application --- v2/internal/platform/systray/windows.go | 16 ++++++++++++++-- v2/pkg/application/application.go | 4 ++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go index 27ff447e1..33882339a 100644 --- a/v2/internal/platform/systray/windows.go +++ b/v2/internal/platform/systray/windows.go @@ -20,6 +20,8 @@ var ( DefWindowProc = user32.MustFindProc("DefWindowProcW") RegisterClassEx = user32.MustFindProc("RegisterClassExW") CreateWindowEx = user32.MustFindProc("CreateWindowExW") + + windowClasses = map[string]win32.HINSTANCE{} ) type Systray struct { @@ -51,7 +53,10 @@ func (p *Systray) Close() { func (p *Systray) SetTitle(_ string) {} func New() (*Systray, error) { - ni := &Systray{lclick: func() {}, rclick: func() {}} + ni := &Systray{ + lclick: func() {}, + rclick: func() {}, + } MainClassName := "WailsSystray" ni.hinst, _ = RegisterWindow(MainClassName, ni.WinProc) @@ -343,6 +348,10 @@ func (p *Systray) updateIcon() error { } func RegisterWindow(name string, proc win32.WindowProc) (win32.HINSTANCE, error) { + instance, exists := windowClasses[name] + if exists { + return instance, nil + } hinst := win32.GetModuleHandle(0) if hinst == 0 { return 0, errors.New("get module handle failed") @@ -367,9 +376,12 @@ func RegisterWindow(name string, proc win32.WindowProc) (win32.HINSTANCE, error) wc.HbrBackground = win32.COLOR_BTNFACE + 1 wc.LpszClassName = win32.MustStringToUTF16Ptr(name) - atom, _, _ := RegisterClassEx.Call(uintptr(unsafe.Pointer(&wc))) + atom, _, e := RegisterClassEx.Call(uintptr(unsafe.Pointer(&wc))) if atom == 0 { + println(e.Error()) return 0, errors.New("register class failed") } + + windowClasses[name] = hi return hi, nil } diff --git a/v2/pkg/application/application.go b/v2/pkg/application/application.go index 2694ce09e..e548e03cb 100644 --- a/v2/pkg/application/application.go +++ b/v2/pkg/application/application.go @@ -50,6 +50,10 @@ func (a *Application) SetApplicationMenu(appMenu *menu.Menu) { // Run starts the application func (a *Application) Run() error { + for _, systemtray := range a.systemTrays { + go systemtray.run() + } + err := applicationInit() if err != nil { return err From 68bdc7c5eb6ba1b5d18c42f9fbe7a63be7d604ea Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Wed, 5 Oct 2022 19:22:03 +1100 Subject: [PATCH 23/48] Support menu.Menu --- v2/internal/platform/menu/windows.go | 9 +++++ v2/internal/platform/systray.go | 4 +-- v2/internal/platform/systray/menu.go | 45 ++++++++++++++++++++----- v2/internal/platform/systray/windows.go | 32 +++++------------- v2/pkg/application/systray.go | 14 ++------ v2/pkg/options/systemtray.go | 3 ++ 6 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 v2/internal/platform/menu/windows.go diff --git a/v2/internal/platform/menu/windows.go b/v2/internal/platform/menu/windows.go new file mode 100644 index 000000000..68ebbcb49 --- /dev/null +++ b/v2/internal/platform/menu/windows.go @@ -0,0 +1,9 @@ +//go:build windows + +package menu + +import "github.com/wailsapp/wails/v2/internal/platform/win32" + +type Menu struct { + menu win32.HMENU +} diff --git a/v2/internal/platform/systray.go b/v2/internal/platform/systray.go index 2f047249c..ed8efcac3 100644 --- a/v2/internal/platform/systray.go +++ b/v2/internal/platform/systray.go @@ -15,9 +15,7 @@ type SysTray interface { Hide() error Run() error Close() - AppendMenu(label string, callback menu.Callback) - AppendMenuItem(item *menu.MenuItem) - AppendSeparator() + SetMenu(menu *menu.Menu) error SetIcons(lightModeIcon, darkModeIcon *options.SystemTrayIcon) error } diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index 5bfa00da0..22b58f084 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -6,10 +6,15 @@ import ( "github.com/wailsapp/wails/v2/pkg/menu" ) -func displayMenu(hwnd win32.HWND, menuItems []*menu.MenuItem) error { - popupMenu := win32.CreatePopupMenu() +type PopupMenu struct { + menu win32.HMENU + parent win32.HWND + menuMapping map[int]*menu.MenuItem +} - for index, item := range menuItems { +func buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu) (map[int]*menu.MenuItem, error) { + menuMapping := make(map[int]*menu.MenuItem) + for index, item := range inputMenu.Items { var ret bool itemID := win32.MenuItemMsgID + index flags := win32.MF_STRING @@ -26,28 +31,52 @@ func displayMenu(hwnd win32.HWND, menuItems []*menu.MenuItem) error { flags = flags | win32.MF_SEPARATOR } - ret = win32.AppendMenu(popupMenu, uintptr(flags), uintptr(itemID), item.Label) + menuMapping[itemID] = item + ret = win32.AppendMenu(parentMenu, uintptr(flags), uintptr(itemID), item.Label) if ret == false { - return errors.New("AppendMenu failed") + return nil, errors.New("AppendMenu failed") } } + return menuMapping, nil +} +func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) { + popupMenu := win32.CreatePopupMenu() + mappings, err := buildMenu(popupMenu, inputMenu) + if err != nil { + return nil, err + } + return &PopupMenu{ + parent: parent, + menu: popupMenu, + menuMapping: mappings, + }, nil +} + +func (p *PopupMenu) ShowAtCursor() error { x, y, ok := win32.GetCursorPos() if ok == false { return errors.New("GetCursorPos failed") } - if win32.SetForegroundWindow(hwnd) == false { + if win32.SetForegroundWindow(p.parent) == false { return errors.New("SetForegroundWindow failed") } - if win32.TrackPopupMenu(popupMenu, win32.TPM_LEFTALIGN, x, y-5, hwnd) == false { + if win32.TrackPopupMenu(p.menu, win32.TPM_LEFTALIGN, x, y-5, p.parent) == false { return errors.New("TrackPopupMenu failed") } - if win32.PostMessage(hwnd, win32.WM_NULL, 0, 0) == 0 { + if win32.PostMessage(p.parent, win32.WM_NULL, 0, 0) == 0 { return errors.New("PostMessage failed") } return nil } + +func (p *PopupMenu) ProcessCommand(cmdMsgID int) { + item := p.menuMapping[cmdMsgID] + if item != nil { + item.Click(&menu.CallbackData{MenuItem: item}) + } +} diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go index 33882339a..ecedccd23 100644 --- a/v2/internal/platform/systray/windows.go +++ b/v2/internal/platform/systray/windows.go @@ -36,7 +36,7 @@ type Systray struct { darkModeIcon win32.HICON currentIcon win32.HICON - Menu []*menu.MenuItem + menu *PopupMenu quit chan struct{} icon *options.SystemTrayIcon @@ -136,19 +136,9 @@ func (p *Systray) HWND() win32.HWND { return p.hwnd } -// AppendMenu add menu item. -func (p *Systray) AppendMenu(label string, onclick menu.Callback) { - p.Menu = append(p.Menu, &menu.MenuItem{Type: menu.TextType, Label: label, Click: onclick}) -} - -// AppendMenuItem add menu item. -func (p *Systray) AppendMenuItem(item *menu.MenuItem) { - p.Menu = append(p.Menu, item) -} - -// AppendSeparator to the menu. -func (p *Systray) AppendSeparator() { - p.Menu = append(p.Menu, menu.Separator()) +func (p *Systray) SetMenu(popupMenu *menu.Menu) (err error) { + p.menu, err = NewPopupMenu(p.hwnd, popupMenu) + return } func (p *Systray) Stop() error { @@ -273,16 +263,16 @@ func (p *Systray) WinProc(hwnd win32.HWND, msg uint32, wparam, lparam uintptr) u case win32.NotifyIconMessageId: if lparam == win32.WM_LBUTTONUP { p.lclick() - if len(p.Menu) > 0 { - err := displayMenu(p.hwnd, p.Menu) + if p.menu != nil { + err := p.menu.ShowAtCursor() if err != nil { return 0 } } } else if lparam == win32.WM_RBUTTONUP { p.rclick() - if len(p.Menu) > 0 { - err := displayMenu(p.hwnd, p.Menu) + if p.menu != nil { + err := p.menu.ShowAtCursor() if err != nil { return 0 } @@ -301,11 +291,7 @@ func (p *Systray) WinProc(hwnd win32.HWND, msg uint32, wparam, lparam uintptr) u cmdMsgID := int(wparam & 0xffff) switch cmdMsgID { default: - if cmdMsgID >= win32.MenuItemMsgID && cmdMsgID < (win32.MenuItemMsgID+len(p.Menu)) { - itemIndex := cmdMsgID - win32.MenuItemMsgID - menuItem := p.Menu[itemIndex] - menuItem.Click(nil) - } + p.menu.ProcessCommand(cmdMsgID) } } diff --git a/v2/pkg/application/systray.go b/v2/pkg/application/systray.go index 58cfdd34a..ed7bc906b 100644 --- a/v2/pkg/application/systray.go +++ b/v2/pkg/application/systray.go @@ -14,6 +14,7 @@ type SystemTray struct { darkModeIcon *options.SystemTrayIcon tooltip string startHidden bool + menu *menu.Menu // The platform specific implementation impl platform.SysTray @@ -27,6 +28,7 @@ func newSystemTray(options *options.SystemTray) *SystemTray { darkModeIcon: options.DarkModeIcon, tooltip: options.Tooltip, startHidden: options.StartHidden, + menu: options.Menu, } } @@ -37,6 +39,7 @@ func (t *SystemTray) run() { if !t.startHidden { t.impl.Show() } + t.impl.SetMenu(t.menu) t.impl.Run() } @@ -44,9 +47,6 @@ func (t *SystemTray) SetTitle(title string) { t.title = title t.impl.SetTitle(title) } -func (t *SystemTray) AppendMenu(label string, callback menu.Callback) { - t.impl.AppendMenu(label, callback) -} func (t *SystemTray) Run() error { t.run() @@ -56,11 +56,3 @@ func (t *SystemTray) Run() error { func (t *SystemTray) Close() { t.impl.Close() } - -func (t *SystemTray) AppendSeperator() { - t.impl.AppendSeparator() -} - -func (t *SystemTray) AppendMenuItem(item *menu.MenuItem) { - t.impl.AppendMenuItem(item) -} diff --git a/v2/pkg/options/systemtray.go b/v2/pkg/options/systemtray.go index 51463c534..14639040e 100644 --- a/v2/pkg/options/systemtray.go +++ b/v2/pkg/options/systemtray.go @@ -1,5 +1,7 @@ package options +import "github.com/wailsapp/wails/v2/pkg/menu" + // SystemTray contains options for the system tray type SystemTray struct { LightModeIcon *SystemTrayIcon @@ -7,6 +9,7 @@ type SystemTray struct { Title string Tooltip string StartHidden bool + Menu *menu.Menu } // SystemTrayIcon represents a system tray icon From abe83f227101855b9f8e88306c1b2388dd6ea110 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 6 Oct 2022 08:21:30 +1100 Subject: [PATCH 24/48] Support traymenu update --- v2/internal/platform/systray.go | 1 + v2/internal/platform/systray/menu.go | 26 +++++++++++++++--------- v2/internal/platform/systray/windows.go | 10 +++++++++ v2/internal/platform/win32/consts.go | 1 + v2/internal/platform/win32/menu.go | 5 +++++ v2/pkg/application/application.go | 1 - v2/pkg/application/systray.go | 27 +++++++++++++++++++++---- 7 files changed, 57 insertions(+), 14 deletions(-) diff --git a/v2/internal/platform/systray.go b/v2/internal/platform/systray.go index ed8efcac3..0a8f69ca2 100644 --- a/v2/internal/platform/systray.go +++ b/v2/internal/platform/systray.go @@ -17,6 +17,7 @@ type SysTray interface { Close() SetMenu(menu *menu.Menu) error SetIcons(lightModeIcon, darkModeIcon *options.SystemTrayIcon) error + Update() } func NewSysTray() SysTray { diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index 22b58f084..23ad949fa 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -10,6 +10,7 @@ type PopupMenu struct { menu win32.HMENU parent win32.HWND menuMapping map[int]*menu.MenuItem + menuData *menu.Menu } func buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu) (map[int]*menu.MenuItem, error) { @@ -40,17 +41,20 @@ func buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu) (map[int]*menu.Menu return menuMapping, nil } +func (p *PopupMenu) Update() error { + var err error + p.menu = win32.CreatePopupMenu() + p.menuMapping, err = buildMenu(p.menu, p.menuData) + return err +} + func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) { - popupMenu := win32.CreatePopupMenu() - mappings, err := buildMenu(popupMenu, inputMenu) - if err != nil { - return nil, err + result := &PopupMenu{ + parent: parent, + menuData: inputMenu, } - return &PopupMenu{ - parent: parent, - menu: popupMenu, - menuMapping: mappings, - }, nil + err := result.Update() + return result, err } func (p *PopupMenu) ShowAtCursor() error { @@ -80,3 +84,7 @@ func (p *PopupMenu) ProcessCommand(cmdMsgID int) { item.Click(&menu.CallbackData{MenuItem: item}) } } + +func (p *PopupMenu) Destroy() { + win32.DestroyMenu(p.menu) +} diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go index ecedccd23..20e386a72 100644 --- a/v2/internal/platform/systray/windows.go +++ b/v2/internal/platform/systray/windows.go @@ -49,6 +49,16 @@ func (p *Systray) Close() { } } +func (p *Systray) Update() { + // Delete old menu + if p.menu != nil { + p.menu.Destroy() + } + + p.menu.Update() + +} + // SetTitle is unused on Windows func (p *Systray) SetTitle(_ string) {} diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go index dca347d98..2fe528fab 100644 --- a/v2/internal/platform/win32/consts.go +++ b/v2/internal/platform/win32/consts.go @@ -19,6 +19,7 @@ var ( procSetForegroundWindow = moduser32.NewProc("SetForegroundWindow") procCreatePopupMenu = moduser32.NewProc("CreatePopupMenu") procTrackPopupMenu = moduser32.NewProc("TrackPopupMenu") + procDestroyMenu = moduser32.NewProc("DestroyMenu") procAppendMenuW = moduser32.NewProc("AppendMenuW") procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx") procGetMessageW = moduser32.NewProc("GetMessageW") diff --git a/v2/internal/platform/win32/menu.go b/v2/internal/platform/win32/menu.go index 332e859e7..9470fdda7 100644 --- a/v2/internal/platform/win32/menu.go +++ b/v2/internal/platform/win32/menu.go @@ -5,6 +5,11 @@ func CreatePopupMenu() HMENU { return HMENU(ret) } +func DestroyMenu(menu HMENU) bool { + ret, _, _ := procDestroyMenu.Call(uintptr(menu)) + return ret != 0 +} + func TrackPopupMenu(menu HMENU, flags uint, x, y int, wnd HWND) bool { ret, _, _ := procTrackPopupMenu.Call( uintptr(menu), diff --git a/v2/pkg/application/application.go b/v2/pkg/application/application.go index e548e03cb..512de94c5 100644 --- a/v2/pkg/application/application.go +++ b/v2/pkg/application/application.go @@ -111,6 +111,5 @@ func (a *Application) On(eventType EventType, callback func()) { func (a *Application) NewSystemTray(options *options.SystemTray) *SystemTray { systemTray := newSystemTray(options) a.systemTrays = append(a.systemTrays, systemTray) - println("created systemTray") return systemTray } diff --git a/v2/pkg/application/systray.go b/v2/pkg/application/systray.go index ed7bc906b..4e0154e39 100644 --- a/v2/pkg/application/systray.go +++ b/v2/pkg/application/systray.go @@ -22,7 +22,6 @@ type SystemTray struct { func newSystemTray(options *options.SystemTray) *SystemTray { return &SystemTray{ - impl: platform.NewSysTray(), title: options.Title, lightModeIcon: options.LightModeIcon, darkModeIcon: options.DarkModeIcon, @@ -33,6 +32,7 @@ func newSystemTray(options *options.SystemTray) *SystemTray { } func (t *SystemTray) run() { + t.impl = platform.NewSysTray() t.impl.SetTitle(t.title) t.impl.SetIcons(t.lightModeIcon, t.darkModeIcon) t.impl.SetTooltip(t.tooltip) @@ -44,8 +44,11 @@ func (t *SystemTray) run() { } func (t *SystemTray) SetTitle(title string) { - t.title = title - t.impl.SetTitle(title) + if t.impl != nil { + t.impl.SetTitle(title) + } else { + t.title = title + } } func (t *SystemTray) Run() error { @@ -54,5 +57,21 @@ func (t *SystemTray) Run() error { } func (t *SystemTray) Close() { - t.impl.Close() + if t.impl != nil { + t.impl.Close() + } +} + +func (t *SystemTray) SetMenu(items *menu.Menu) { + if t.impl != nil { + t.impl.SetMenu(t.menu) + } else { + t.menu = items + } +} + +func (t *SystemTray) Update() { + if t.impl != nil { + t.impl.Update() + } } From 0664c518329be1da3b20402d0118c7108bda25cd Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 6 Oct 2022 19:49:48 +1100 Subject: [PATCH 25/48] Fix GetMessage bug --- v2/internal/platform/win32/consts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go index 2fe528fab..0490aee3d 100644 --- a/v2/internal/platform/win32/consts.go +++ b/v2/internal/platform/win32/consts.go @@ -121,7 +121,7 @@ func GetModuleHandle(value uintptr) uintptr { } func GetMessage(msg *MSG) uintptr { - rt, _, _ := procGetMessageW.Call(uintptr(unsafe.Pointer(&msg)), 0, 0, 0) + rt, _, _ := procGetMessageW.Call(uintptr(unsafe.Pointer(msg)), 0, 0, 0) return rt } From 249dc81872cf59c23f7d9c3e8a1c86d5719fca71 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 6 Oct 2022 20:30:34 +1100 Subject: [PATCH 26/48] Fix GetMessage bug. Refactor ShellNotifyIcon. Application shutdown once. --- v2/internal/platform/systray.go | 2 +- v2/internal/platform/systray/windows.go | 27 +++++++++---------------- v2/internal/platform/win32/consts.go | 9 +++++++-- v2/pkg/application/application.go | 13 ++++++++---- v2/pkg/application/systray.go | 6 ++++-- 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/v2/internal/platform/systray.go b/v2/internal/platform/systray.go index 0a8f69ca2..9625f1a7e 100644 --- a/v2/internal/platform/systray.go +++ b/v2/internal/platform/systray.go @@ -17,7 +17,7 @@ type SysTray interface { Close() SetMenu(menu *menu.Menu) error SetIcons(lightModeIcon, darkModeIcon *options.SystemTrayIcon) error - Update() + Update() error } func NewSysTray() SysTray { diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go index 20e386a72..0273a1097 100644 --- a/v2/internal/platform/systray/windows.go +++ b/v2/internal/platform/systray/windows.go @@ -49,14 +49,13 @@ func (p *Systray) Close() { } } -func (p *Systray) Update() { +func (p *Systray) Update() error { // Delete old menu if p.menu != nil { p.menu.Destroy() } - p.menu.Update() - + return p.menu.Update() } // SetTitle is unused on Windows @@ -123,15 +122,13 @@ func New() (*Systray, error) { } nid.CbSize = uint32(unsafe.Sizeof(nid)) - ret := win32.ShellNotifyIcon(win32.NIM_ADD, &nid) - if ret == 0 { + if !win32.ShellNotifyIcon(win32.NIM_ADD, &nid) { return nil, errors.New("shell notify create failed") } nid.UVersion = win32.NOTIFYICON_VERSION - ret = win32.ShellNotifyIcon(win32.NIM_SETVERSION, &nid) - if ret == 0 { + if !win32.ShellNotifyIcon(win32.NIM_SETVERSION, &nid) { return nil, errors.New("shell notify version failed") } @@ -153,8 +150,8 @@ func (p *Systray) SetMenu(popupMenu *menu.Menu) (err error) { func (p *Systray) Stop() error { nid := p.newNotifyIconData() - ret := win32.ShellNotifyIcon(win32.NIM_DELETE, &nid) - if ret == 0 { + win32.PostQuitMessage(0) + if !win32.ShellNotifyIcon(win32.NIM_DELETE, &nid) { return errors.New("shell notify delete failed") } return nil @@ -173,8 +170,7 @@ func (p *Systray) SetTooltip(tooltip string) error { nid.UFlags = win32.NIF_TIP copy(nid.SzTip[:], win32.MustUTF16FromString(tooltip)) - ret := win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) - if ret == 0 { + if !win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) { return errors.New("shell notify tooltip failed") } return nil @@ -192,8 +188,7 @@ func (p *Systray) ShowMessage(title, msg string, bigIcon bool) error { copy(nid.SzInfoTitle[:], win32.MustUTF16FromString(title)) copy(nid.SzInfo[:], win32.MustUTF16FromString(msg)) - ret := win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) - if ret == 0 { + if !win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) { return errors.New("shell notify tooltip failed") } return nil @@ -224,8 +219,7 @@ func (p *Systray) setVisible(visible bool) error { nid.DwState = win32.NIS_HIDDEN } - ret := win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) - if ret == 0 { + if !win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) { return errors.New("shell notify tooltip failed") } return nil @@ -261,8 +255,7 @@ func (p *Systray) setIcon(hicon win32.HICON) error { nid.HIcon = hicon } - ret := win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) - if ret == 0 { + if !win32.ShellNotifyIcon(win32.NIM_MODIFY, &nid) { return errors.New("shell notify icon failed") } return nil diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go index 0490aee3d..b577bd011 100644 --- a/v2/internal/platform/win32/consts.go +++ b/v2/internal/platform/win32/consts.go @@ -26,6 +26,7 @@ var ( procIsDialogMessage = moduser32.NewProc("IsDialogMessageW") procTranslateMessage = moduser32.NewProc("TranslateMessage") procDispatchMessage = moduser32.NewProc("DispatchMessageW") + procPostQuitMessage = moduser32.NewProc("PostQuitMessage") modshell32 = syscall.NewLazyDLL("shell32.dll") procShellNotifyIcon = modshell32.NewProc("Shell_NotifyIconW") @@ -135,9 +136,9 @@ func PostMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { return ret } -func ShellNotifyIcon(cmd uintptr, nid *NOTIFYICONDATA) uintptr { +func ShellNotifyIcon(cmd uintptr, nid *NOTIFYICONDATA) bool { ret, _, _ := procShellNotifyIcon.Call(cmd, uintptr(unsafe.Pointer(nid))) - return ret + return ret == 1 } func IsDialogMessage(hwnd HWND, msg *MSG) uintptr { @@ -154,3 +155,7 @@ func DispatchMessage(msg *MSG) uintptr { ret, _, _ := procDispatchMessage.Call(uintptr(unsafe.Pointer(msg))) return ret } + +func PostQuitMessage(exitCode int32) { + procPostQuitMessage.Call(uintptr(exitCode)) +} diff --git a/v2/pkg/application/application.go b/v2/pkg/application/application.go index 512de94c5..03d98ebd7 100644 --- a/v2/pkg/application/application.go +++ b/v2/pkg/application/application.go @@ -6,6 +6,7 @@ import ( "github.com/wailsapp/wails/v2/internal/signal" "github.com/wailsapp/wails/v2/pkg/menu" "github.com/wailsapp/wails/v2/pkg/options" + "sync" ) // Application is the main Wails application @@ -18,6 +19,8 @@ type Application struct { // running flag running bool + + shutdown sync.Once } // NewWithOptions creates a new Application with the given options @@ -81,10 +84,12 @@ func (a *Application) Run() error { // Quit will shut down the application func (a *Application) Quit() { - for _, systray := range a.systemTrays { - systray.Close() - } - a.application.Shutdown() + a.shutdown.Do(func() { + for _, systray := range a.systemTrays { + systray.Close() + } + a.application.Shutdown() + }) } // Bind the given struct to the application diff --git a/v2/pkg/application/systray.go b/v2/pkg/application/systray.go index 4e0154e39..ba52d097c 100644 --- a/v2/pkg/application/systray.go +++ b/v2/pkg/application/systray.go @@ -59,6 +59,7 @@ func (t *SystemTray) Run() error { func (t *SystemTray) Close() { if t.impl != nil { t.impl.Close() + t.impl = nil } } @@ -70,8 +71,9 @@ func (t *SystemTray) SetMenu(items *menu.Menu) { } } -func (t *SystemTray) Update() { +func (t *SystemTray) Update() error { if t.impl != nil { - t.impl.Update() + return t.impl.Update() } + return nil } From 181ba423a3dfb1b4866e7408d09ea7616622c174 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 6 Oct 2022 23:13:42 +1100 Subject: [PATCH 27/48] Support submenus --- v2/internal/platform/systray/menu.go | 33 ++++++++++++++++++---------- v2/internal/platform/win32/consts.go | 1 + 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index 23ad949fa..685356c49 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -13,11 +13,10 @@ type PopupMenu struct { menuData *menu.Menu } -func buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu) (map[int]*menu.MenuItem, error) { - menuMapping := make(map[int]*menu.MenuItem) +func (p *PopupMenu) buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu, startindex int) error { for index, item := range inputMenu.Items { var ret bool - itemID := win32.MenuItemMsgID + index + itemID := index + startindex flags := win32.MF_STRING if item.Disabled { flags = flags | win32.MF_GRAYED @@ -31,27 +30,39 @@ func buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu) (map[int]*menu.Menu if item.IsSeparator() { flags = flags | win32.MF_SEPARATOR } + if item.SubMenu != nil { + flags = flags | win32.MF_POPUP + submenu := win32.CreatePopupMenu() + err := p.buildMenu(submenu, item.SubMenu, itemID) + if err != nil { + return err + } + ret = win32.AppendMenu(parentMenu, uintptr(flags), uintptr(submenu), item.Label) + if ret == false { + return errors.New("AppendMenu failed") + } + continue + } - menuMapping[itemID] = item + p.menuMapping[itemID] = item ret = win32.AppendMenu(parentMenu, uintptr(flags), uintptr(itemID), item.Label) if ret == false { - return nil, errors.New("AppendMenu failed") + return errors.New("AppendMenu failed") } } - return menuMapping, nil + return nil } func (p *PopupMenu) Update() error { - var err error p.menu = win32.CreatePopupMenu() - p.menuMapping, err = buildMenu(p.menu, p.menuData) - return err + return p.buildMenu(p.menu, p.menuData, win32.MenuItemMsgID) } func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) { result := &PopupMenu{ - parent: parent, - menuData: inputMenu, + parent: parent, + menuData: inputMenu, + menuMapping: make(map[int]*menu.MenuItem), } err := result.Update() return result, err diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go index b577bd011..0c9435260 100644 --- a/v2/internal/platform/win32/consts.go +++ b/v2/internal/platform/win32/consts.go @@ -105,6 +105,7 @@ const ( MF_DISABLED = 0x00000002 MF_SEPARATOR = 0x00000800 MF_CHECKED = 0x00000008 + MF_POPUP = 0x00000010 MF_MENUBARBREAK = 0x00000020 TPM_LEFTALIGN = 0x0000 From b5478e52db353398e6717f9dc8130ed21861b558 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 7 Oct 2022 20:02:58 +1100 Subject: [PATCH 28/48] Support checkbox logic. Support duplicate checkboxes --- .gitignore | 3 +- v2/internal/platform/systray/menu.go | 34 +++++++++++++----- v2/internal/platform/win32/consts.go | 2 ++ v2/internal/platform/win32/menu.go | 9 +++++ v2/pkg/menu/menuitem.go | 53 +++++++++++++++++++--------- 5 files changed, 76 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 6f2284002..bc604b5dd 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,5 @@ v2/cmd/wails/internal/commands/initialise/templates/testtemplates/ .env /website/static/img/.cache.json -v2/internal/frontend/desktop/darwin/test.xcodeproj \ No newline at end of file +v2/internal/frontend/desktop/darwin/test.xcodeproj +TODO.md \ No newline at end of file diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index 685356c49..f54c4bab2 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -7,10 +7,11 @@ import ( ) type PopupMenu struct { - menu win32.HMENU - parent win32.HWND - menuMapping map[int]*menu.MenuItem - menuData *menu.Menu + menu win32.HMENU + parent win32.HWND + menuMapping map[int]*menu.MenuItem + checkboxItems map[*menu.MenuItem][]int + menuData *menu.Menu } func (p *PopupMenu) buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu, startindex int) error { @@ -45,6 +46,9 @@ func (p *PopupMenu) buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu, star } p.menuMapping[itemID] = item + if item.IsCheckbox() { + p.checkboxItems[item] = append(p.checkboxItems[item], itemID) + } ret = win32.AppendMenu(parentMenu, uintptr(flags), uintptr(itemID), item.Label) if ret == false { return errors.New("AppendMenu failed") @@ -60,9 +64,10 @@ func (p *PopupMenu) Update() error { func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) { result := &PopupMenu{ - parent: parent, - menuData: inputMenu, - menuMapping: make(map[int]*menu.MenuItem), + parent: parent, + menuData: inputMenu, + menuMapping: make(map[int]*menu.MenuItem), + checkboxItems: make(map[*menu.MenuItem][]int), } err := result.Update() return result, err @@ -92,7 +97,20 @@ func (p *PopupMenu) ShowAtCursor() error { func (p *PopupMenu) ProcessCommand(cmdMsgID int) { item := p.menuMapping[cmdMsgID] if item != nil { - item.Click(&menu.CallbackData{MenuItem: item}) + if item.Type == menu.CheckboxType { + item.Checked = !item.Checked + var checkState uint = win32.MF_UNCHECKED + if item.Checked { + checkState = win32.MF_CHECKED + } + for _, menuID := range p.checkboxItems[item] { + win32.CheckMenuItem(p.menu, int32(menuID), checkState) + } + // TODO: Check duplicate menu items + } + if item.Click != nil { + item.Click(&menu.CallbackData{MenuItem: item}) + } } } diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go index 0c9435260..2617405fa 100644 --- a/v2/internal/platform/win32/consts.go +++ b/v2/internal/platform/win32/consts.go @@ -21,6 +21,7 @@ var ( procTrackPopupMenu = moduser32.NewProc("TrackPopupMenu") procDestroyMenu = moduser32.NewProc("DestroyMenu") procAppendMenuW = moduser32.NewProc("AppendMenuW") + procCheckMenuItem = moduser32.NewProc("CheckMenuItem") procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx") procGetMessageW = moduser32.NewProc("GetMessageW") procIsDialogMessage = moduser32.NewProc("IsDialogMessageW") @@ -104,6 +105,7 @@ const ( MF_GRAYED = 0x00000001 MF_DISABLED = 0x00000002 MF_SEPARATOR = 0x00000800 + MF_UNCHECKED = 0x00000000 MF_CHECKED = 0x00000008 MF_POPUP = 0x00000010 MF_MENUBARBREAK = 0x00000020 diff --git a/v2/internal/platform/win32/menu.go b/v2/internal/platform/win32/menu.go index 9470fdda7..25a151dac 100644 --- a/v2/internal/platform/win32/menu.go +++ b/v2/internal/platform/win32/menu.go @@ -32,3 +32,12 @@ func AppendMenu(menu HMENU, flags uintptr, id uintptr, text string) bool { ) return ret != 0 } + +func CheckMenuItem(menu HMENU, id int32, flags uint) uint { + ret, _, _ := procCheckMenuItem.Call( + uintptr(menu), + uintptr(id), + uintptr(flags), + ) + return uint(ret) +} diff --git a/v2/pkg/menu/menuitem.go b/v2/pkg/menu/menuitem.go index ac5ebd7be..6ab928857 100644 --- a/v2/pkg/menu/menuitem.go +++ b/v2/pkg/menu/menuitem.go @@ -6,11 +6,6 @@ import ( "github.com/wailsapp/wails/v2/pkg/menu/keys" ) -type MenuItemImpl interface { - SetChecked(bool) - SetLabel(string) -} - // MenuItem represents a menuitem contained in a menu type MenuItem struct { // Label is what appears as the menu text @@ -58,9 +53,6 @@ type MenuItem struct { // Used for locking when removing elements removeLock sync.Mutex - - // Implementation of the runtime methods - Impl MenuItemImpl } // Parent returns the parent of the menu item. @@ -224,25 +216,54 @@ func (m *MenuItem) insertItemAtIndex(index int, target *MenuItem) bool { return true } -func (m *MenuItem) SetChecked(b bool) { - if m.Checked != b { - m.Checked = b - m.Impl.SetChecked(b) - } -} - func (m *MenuItem) SetLabel(name string) { if m.Label == name { return } m.Label = name - m.Impl.SetLabel(name) } func (m *MenuItem) IsSeparator() bool { return m.Type == SeparatorType } +func (m *MenuItem) IsCheckbox() bool { + return m.Type == CheckboxType +} + +func (m *MenuItem) Disable() *MenuItem { + m.Disabled = true + return m +} + +func (m *MenuItem) Enable() *MenuItem { + m.Disabled = false + return m +} + +func (m *MenuItem) OnClick(click Callback) *MenuItem { + m.Click = click + return m +} + +func (m *MenuItem) SetAccelerator(acc *keys.Accelerator) *MenuItem { + m.Accelerator = acc + return m +} + +func (m *MenuItem) SetChecked(value bool) *MenuItem { + m.Checked = value + m.Type = CheckboxType + return m +} + +func Label(label string) *MenuItem { + return &MenuItem{ + Type: TextType, + Label: label, + } +} + // Text is a helper to create basic Text menu items func Text(label string, accelerator *keys.Accelerator, click Callback) *MenuItem { return &MenuItem{ From d6f20d5f0bc441ec3c09bdc809b998bf75c97342 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 7 Oct 2022 20:15:19 +1100 Subject: [PATCH 29/48] menu refactor --- v2/internal/platform/systray/menu.go | 18 +++++------- v2/internal/platform/win32/menu.go | 43 +++++++++++++++++++++------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index f54c4bab2..1e15edbf5 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -7,14 +7,14 @@ import ( ) type PopupMenu struct { - menu win32.HMENU + menu win32.PopupMenu parent win32.HWND menuMapping map[int]*menu.MenuItem checkboxItems map[*menu.MenuItem][]int menuData *menu.Menu } -func (p *PopupMenu) buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu, startindex int) error { +func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, startindex int) error { for index, item := range inputMenu.Items { var ret bool itemID := index + startindex @@ -38,7 +38,7 @@ func (p *PopupMenu) buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu, star if err != nil { return err } - ret = win32.AppendMenu(parentMenu, uintptr(flags), uintptr(submenu), item.Label) + ret = parentMenu.Append(uintptr(flags), uintptr(submenu), item.Label) if ret == false { return errors.New("AppendMenu failed") } @@ -49,7 +49,7 @@ func (p *PopupMenu) buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu, star if item.IsCheckbox() { p.checkboxItems[item] = append(p.checkboxItems[item], itemID) } - ret = win32.AppendMenu(parentMenu, uintptr(flags), uintptr(itemID), item.Label) + ret = parentMenu.Append(uintptr(flags), uintptr(itemID), item.Label) if ret == false { return errors.New("AppendMenu failed") } @@ -83,7 +83,7 @@ func (p *PopupMenu) ShowAtCursor() error { return errors.New("SetForegroundWindow failed") } - if win32.TrackPopupMenu(p.menu, win32.TPM_LEFTALIGN, x, y-5, p.parent) == false { + if p.menu.Track(win32.TPM_LEFTALIGN, x, y-5, p.parent) == false { return errors.New("TrackPopupMenu failed") } @@ -99,12 +99,8 @@ func (p *PopupMenu) ProcessCommand(cmdMsgID int) { if item != nil { if item.Type == menu.CheckboxType { item.Checked = !item.Checked - var checkState uint = win32.MF_UNCHECKED - if item.Checked { - checkState = win32.MF_CHECKED - } for _, menuID := range p.checkboxItems[item] { - win32.CheckMenuItem(p.menu, int32(menuID), checkState) + p.menu.Check(uintptr(menuID), item.Checked) } // TODO: Check duplicate menu items } @@ -115,5 +111,5 @@ func (p *PopupMenu) ProcessCommand(cmdMsgID int) { } func (p *PopupMenu) Destroy() { - win32.DestroyMenu(p.menu) + p.menu.Destroy() } diff --git a/v2/internal/platform/win32/menu.go b/v2/internal/platform/win32/menu.go index 25a151dac..56fb97b01 100644 --- a/v2/internal/platform/win32/menu.go +++ b/v2/internal/platform/win32/menu.go @@ -1,18 +1,25 @@ package win32 -func CreatePopupMenu() HMENU { +type Menu HMENU +type PopupMenu Menu + +func CreatePopupMenu() PopupMenu { ret, _, _ := procCreatePopupMenu.Call(0, 0, 0, 0) - return HMENU(ret) + return PopupMenu(ret) } -func DestroyMenu(menu HMENU) bool { - ret, _, _ := procDestroyMenu.Call(uintptr(menu)) +func (m Menu) Destroy() bool { + ret, _, _ := procDestroyMenu.Call(uintptr(m)) return ret != 0 } -func TrackPopupMenu(menu HMENU, flags uint, x, y int, wnd HWND) bool { +func (p PopupMenu) Destroy() bool { + return Menu(p).Destroy() +} + +func (p PopupMenu) Track(flags uint, x, y int, wnd HWND) bool { ret, _, _ := procTrackPopupMenu.Call( - uintptr(menu), + uintptr(p), uintptr(flags), uintptr(x), uintptr(y), @@ -23,9 +30,13 @@ func TrackPopupMenu(menu HMENU, flags uint, x, y int, wnd HWND) bool { return ret != 0 } -func AppendMenu(menu HMENU, flags uintptr, id uintptr, text string) bool { +func (p PopupMenu) Append(flags uintptr, id uintptr, text string) bool { + return Menu(p).Append(flags, id, text) +} + +func (m Menu) Append(flags uintptr, id uintptr, text string) bool { ret, _, _ := procAppendMenuW.Call( - uintptr(menu), + uintptr(m), flags, id, MustStringToUTF16uintptr(text), @@ -33,10 +44,22 @@ func AppendMenu(menu HMENU, flags uintptr, id uintptr, text string) bool { return ret != 0 } -func CheckMenuItem(menu HMENU, id int32, flags uint) uint { +func (p PopupMenu) Check(id uintptr, checked bool) bool { + return Menu(p).Check(id, checked) +} + +func (m Menu) Check(id uintptr, check bool) bool { + var checkState uint = MF_UNCHECKED + if check { + checkState = MF_CHECKED + } + return CheckMenuItem(HMENU(m), id, checkState) != 0 +} + +func CheckMenuItem(menu HMENU, id uintptr, flags uint) uint { ret, _, _ := procCheckMenuItem.Call( uintptr(menu), - uintptr(id), + id, uintptr(flags), ) return uint(ret) From 5fab671af371a1fc52ecf7527073676683c2034d Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 8 Oct 2022 07:45:29 +1100 Subject: [PATCH 30/48] Support Hidden attribute. Add SetTooltip & SetIcons to SystemTray. Add Show & Hide to menuItem --- v2/internal/platform/systray/menu.go | 3 +++ v2/pkg/application/systray.go | 18 ++++++++++++++++++ v2/pkg/menu/menuitem.go | 10 ++++++++++ 3 files changed, 31 insertions(+) diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index 1e15edbf5..057d5bf37 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -16,6 +16,9 @@ type PopupMenu struct { func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, startindex int) error { for index, item := range inputMenu.Items { + if item.Hidden { + continue + } var ret bool itemID := index + startindex flags := win32.MF_STRING diff --git a/v2/pkg/application/systray.go b/v2/pkg/application/systray.go index ba52d097c..00965e41f 100644 --- a/v2/pkg/application/systray.go +++ b/v2/pkg/application/systray.go @@ -77,3 +77,21 @@ func (t *SystemTray) Update() error { } return nil } + +func (t *SystemTray) SetTooltip(s string) { + if t.impl != nil { + t.impl.SetTooltip(s) + } else { + t.tooltip = s + } +} + +func (t *SystemTray) SetIcons(lightModeIcon *options.SystemTrayIcon, darkModeIcon *options.SystemTrayIcon) { + if t.impl != nil { + t.impl.SetIcons(lightModeIcon, darkModeIcon) + } else { + t.lightModeIcon = lightModeIcon + t.darkModeIcon = darkModeIcon + } + +} diff --git a/v2/pkg/menu/menuitem.go b/v2/pkg/menu/menuitem.go index 6ab928857..013eb6bf2 100644 --- a/v2/pkg/menu/menuitem.go +++ b/v2/pkg/menu/menuitem.go @@ -257,6 +257,16 @@ func (m *MenuItem) SetChecked(value bool) *MenuItem { return m } +func (m *MenuItem) Hide() *MenuItem { + m.Hidden = true + return m +} + +func (m *MenuItem) Show() *MenuItem { + m.Hidden = false + return m +} + func Label(label string) *MenuItem { return &MenuItem{ Type: TextType, From 12a309c8a52ab6bc0498ce5230c91c0b5ffc99ee Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 8 Oct 2022 08:02:02 +1100 Subject: [PATCH 31/48] Update menu docs --- website/docs/reference/menus.mdx | 37 +++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/website/docs/reference/menus.mdx b/website/docs/reference/menus.mdx index 1c2d3f5b7..05038b960 100644 --- a/website/docs/reference/menus.mdx +++ b/website/docs/reference/menus.mdx @@ -80,17 +80,28 @@ type MenuItem struct { } ``` -| Field | Type | Notes | -| ----------- | ---------------------------------- | ------------------------------------------------------------- | -| Label | string | The menu text | -| Accelerator | [\*keys.Accelerator](#accelerator) | Key binding for this menu item | -| Type | [Type](#type) | Type of MenuItem | -| Disabled | bool | Disables the menu item | -| Hidden | bool | Hides this menu item | -| Checked | bool | Adds check to item (Checkbox & Radio types) | -| SubMenu | [\*Menu](#menu) | Sets the submenu | -| Click | [Callback](#callback) | Callback function when menu clicked | -| Role | string | Defines a [role](#role) for this menu item. Mac only for now. | +| Field | Type | Notes | +| ----------- | ---------------------------------- |------------------------------------------------------------------------------------------| +| Label | string | The menu text | +| Accelerator | [\*keys.Accelerator](#accelerator) | Key binding for this menu item | +| Type | [Type](#type) | Type of MenuItem | +| Disabled | bool | Disables the menu item | +| Hidden | bool | Hides this menu item | +| Checked | bool | Adds check to item (Checkbox & Radio types). Updated automatically when item is clicked. | +| SubMenu | [\*Menu](#menu) | Sets the submenu | +| Click | [Callback](#callback) | Callback function when menu clicked | +| Role | string | Defines a [role](#role) for this menu item. Mac only for now. | + +### Keeping menu items in sync + +A menuitem can be reused in multiple menus. This is useful for keeping menu items in sync. For example, if you have a +"Quit" menu item, you can add it to both the Application menu and a system tray menu. When the user clicks the menu item, +the callback will be called only once. + +For checkbox and radio menu items, the state of the menu item will be kept in sync. For example, if you have a "Dark Mode" +menu item in the Application menu and a system tray menu, when the user clicks the menu item in the Application menu, the +state of the menu item in the system tray menu will also be updated. For radio menu items that are used in multiple places, +clicking one will uncheck all others in all groups that the menu item is used in. ### Accelerator @@ -104,7 +115,7 @@ Example: myShortcut := keys.CmdOrCtrl("o") ``` -Keys are any single character on a keyboard with the exception of `+`, which is defined as `plus`. +Keys are any single character on a keyboard except for `+`, which is defined as `plus`. Some keys cannot be represented as characters so there are a set of named characters that may be used: | | | | | @@ -219,7 +230,7 @@ type CallbackData struct { ``` The function is given a `CallbackData` struct which indicates which menu item triggered the callback. This is useful when -using radio groups that may share a callback. +using radio groups that may share a callback. If the menuitem is a checkbox, the `Checked` property will be set to the new value of the checkbox. ### Role From c5ad7de9cf9d68bb7a0ca247956ad97cd9be7c60 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 8 Oct 2022 10:10:39 +1100 Subject: [PATCH 32/48] Menu to follow theme --- v2/internal/platform/systray/windows.go | 4 + v2/internal/platform/win32/consts.go | 78 +++++++++++++++++ v2/internal/platform/win32/theme.go | 110 ++++++++++++++++++++++++ 3 files changed, 192 insertions(+) diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go index 0273a1097..3fec9a59f 100644 --- a/v2/internal/platform/systray/windows.go +++ b/v2/internal/platform/systray/windows.go @@ -336,6 +336,10 @@ func (p *Systray) updateIcon() error { return p.setIcon(newIcon) } +func (p *Systray) updateTheme() { + //win32.SetTheme(p.hwnd, win32.IsCurrentlyDarkMode()) +} + func RegisterWindow(name string, proc win32.WindowProc) (win32.HINSTANCE, error) { instance, exists := windowClasses[name] if exists { diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go index 2617405fa..d9055e240 100644 --- a/v2/internal/platform/win32/consts.go +++ b/v2/internal/platform/win32/consts.go @@ -1,6 +1,8 @@ package win32 import ( + "github.com/wailsapp/wails/v2/internal/system/operatingsystem" + "golang.org/x/sys/windows" "syscall" "unsafe" ) @@ -28,11 +30,79 @@ var ( procTranslateMessage = moduser32.NewProc("TranslateMessage") procDispatchMessage = moduser32.NewProc("DispatchMessageW") procPostQuitMessage = moduser32.NewProc("PostQuitMessage") + procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") modshell32 = syscall.NewLazyDLL("shell32.dll") procShellNotifyIcon = modshell32.NewProc("Shell_NotifyIconW") + + moddwmapi = syscall.NewLazyDLL("dwmapi.dll") + procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") + + moduxtheme = syscall.NewLazyDLL("uxtheme.dll") + procSetWindowTheme = moduxtheme.NewProc("SetWindowTheme") + + AllowDarkModeForWindow func(HWND, bool) uintptr + SetPreferredAppMode func(int32) uintptr ) +type PreferredAppMode = int32 + +const ( + PreferredAppModeDefault PreferredAppMode = iota + PreferredAppModeAllowDark + PreferredAppModeForceDark + PreferredAppModeForceLight + PreferredAppModeMax +) + +/* +RtlGetNtVersionNumbers = void (LPDWORD major, LPDWORD minor, LPDWORD build) // 1809 17763 +ShouldAppsUseDarkMode = bool () // ordinal 132 +AllowDarkModeForWindow = bool (HWND hWnd, bool allow) // ordinal 133 +AllowDarkModeForApp = bool (bool allow) // ordinal 135, removed since 18334 +FlushMenuThemes = void () // ordinal 136 +RefreshImmersiveColorPolicyState = void () // ordinal 104 +IsDarkModeAllowedForWindow = bool (HWND hWnd) // ordinal 137 +GetIsImmersiveColorUsingHighContrast = bool (IMMERSIVE_HC_CACHE_MODE mode) // ordinal 106 +OpenNcThemeData = HTHEME (HWND hWnd, LPCWSTR pszClassList) // ordinal 49 +// Insider 18290 +ShouldSystemUseDarkMode = bool () // ordinal 138 +// Insider 18334 +SetPreferredAppMode = PreferredAppMode (PreferredAppMode appMode) // ordinal 135, since 18334 +IsDarkModeAllowedForApp = bool () // ordinal 139 +*/ +func init() { + if IsWindowsVersionAtLeast(10, 0, 18334) { + + // AllowDarkModeForWindow is only available on Windows 10+ + uxtheme, err := windows.LoadLibrary("uxtheme.dll") + if err == nil { + procAllowDarkModeForWindow, err := windows.GetProcAddressByOrdinal(uxtheme, uintptr(133)) + if err == nil { + AllowDarkModeForWindow = func(hwnd HWND, allow bool) uintptr { + var allowInt int32 + if allow { + allowInt = 1 + } + ret, _, _ := syscall.SyscallN(procAllowDarkModeForWindow, uintptr(hwnd), uintptr(allowInt)) + return ret + } + } + } + + // SetPreferredAppMode is only available on Windows 10+ + procSetPreferredAppMode, err := windows.GetProcAddressByOrdinal(uxtheme, uintptr(135)) + if err == nil { + SetPreferredAppMode = func(mode int32) uintptr { + ret, _, _ := syscall.SyscallN(procSetPreferredAppMode, uintptr(mode)) + return ret + } + SetPreferredAppMode(PreferredAppModeAllowDark) + } + } + +} + type HANDLE uintptr type HINSTANCE HANDLE type HICON HANDLE @@ -117,6 +187,14 @@ const ( CS_HREDRAW = 0x0002 ) +var windowsVersion, _ = operatingsystem.GetWindowsVersionInfo() + +func IsWindowsVersionAtLeast(major, minor, buildNumber int) bool { + return windowsVersion.Major >= major && + windowsVersion.Minor >= minor && + windowsVersion.Build >= buildNumber +} + type WindowProc func(hwnd HWND, msg uint32, wparam, lparam uintptr) uintptr func GetModuleHandle(value uintptr) uintptr { diff --git a/v2/internal/platform/win32/theme.go b/v2/internal/platform/win32/theme.go index d5a23eca4..c15d73a3a 100644 --- a/v2/internal/platform/win32/theme.go +++ b/v2/internal/platform/win32/theme.go @@ -2,8 +2,100 @@ package win32 import ( "golang.org/x/sys/windows/registry" + "unsafe" ) +type DWMWINDOWATTRIBUTE int32 + +const DwmwaUseImmersiveDarkModeBefore20h1 DWMWINDOWATTRIBUTE = 19 +const DwmwaUseImmersiveDarkMode DWMWINDOWATTRIBUTE = 20 +const DwmwaBorderColor DWMWINDOWATTRIBUTE = 34 +const DwmwaCaptionColor DWMWINDOWATTRIBUTE = 35 +const DwmwaTextColor DWMWINDOWATTRIBUTE = 36 +const DwmwaSystemBackdropType DWMWINDOWATTRIBUTE = 38 + +const SPI_GETHIGHCONTRAST = 0x0042 +const HCF_HIGHCONTRASTON = 0x00000001 + +// BackdropType defines the type of translucency we wish to use +type BackdropType int32 + +func dwmSetWindowAttribute(hwnd HWND, dwAttribute DWMWINDOWATTRIBUTE, pvAttribute unsafe.Pointer, cbAttribute uintptr) { + ret, _, err := procDwmSetWindowAttribute.Call( + uintptr(hwnd), + uintptr(dwAttribute), + uintptr(pvAttribute), + cbAttribute) + if ret != 0 { + _ = err + // println(err.Error()) + } +} + +func SupportsThemes() bool { + // We can't support Windows versions before 17763 + return IsWindowsVersionAtLeast(10, 0, 17763) +} + +func SupportsCustomThemes() bool { + return IsWindowsVersionAtLeast(10, 0, 17763) +} + +func SupportsBackdropTypes() bool { + return IsWindowsVersionAtLeast(10, 0, 22621) +} + +func SupportsImmersiveDarkMode() bool { + return IsWindowsVersionAtLeast(10, 0, 18985) +} + +func SetTheme(hwnd HWND, useDarkMode bool) { + if SupportsThemes() { + attr := DwmwaUseImmersiveDarkModeBefore20h1 + if SupportsImmersiveDarkMode() { + attr = DwmwaUseImmersiveDarkMode + } + var winDark int32 + if useDarkMode { + winDark = 1 + } + dwmSetWindowAttribute(hwnd, attr, unsafe.Pointer(&winDark), unsafe.Sizeof(winDark)) + } +} + +func EnableTranslucency(hwnd HWND, backdrop BackdropType) { + if SupportsBackdropTypes() { + dwmSetWindowAttribute(hwnd, DwmwaSystemBackdropType, unsafe.Pointer(&backdrop), unsafe.Sizeof(backdrop)) + } else { + println("Warning: Translucency type unavailable on Windows < 22621") + } +} + +func SetTitleBarColour(hwnd HWND, titleBarColour int32) { + dwmSetWindowAttribute(hwnd, DwmwaCaptionColor, unsafe.Pointer(&titleBarColour), unsafe.Sizeof(titleBarColour)) +} + +func SetTitleTextColour(hwnd HWND, titleTextColour int32) { + dwmSetWindowAttribute(hwnd, DwmwaTextColor, unsafe.Pointer(&titleTextColour), unsafe.Sizeof(titleTextColour)) +} + +func SetBorderColour(hwnd HWND, titleBorderColour int32) { + dwmSetWindowAttribute(hwnd, DwmwaBorderColor, unsafe.Pointer(&titleBorderColour), unsafe.Sizeof(titleBorderColour)) +} + +func SetWindowTheme(hwnd HWND, appName string, subIdList string) uintptr { + var subID uintptr + if subIdList != "" { + subID = MustStringToUTF16uintptr(subIdList) + } + ret, _, _ := procSetWindowTheme.Call( + uintptr(hwnd), + MustStringToUTF16uintptr(appName), + subID, + ) + + return ret +} func IsCurrentlyDarkMode() bool { key, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.QUERY_VALUE) if err != nil { @@ -17,3 +109,21 @@ func IsCurrentlyDarkMode() bool { } return AppsUseLightTheme == 0 } + +type highContrast struct { + CbSize uint32 + DwFlags uint32 + LpszDefaultScheme *int16 +} + +func IsCurrentlyHighContrastMode() bool { + var result highContrast + result.CbSize = uint32(unsafe.Sizeof(result)) + res, _, err := procSystemParametersInfo.Call(SPI_GETHIGHCONTRAST, uintptr(result.CbSize), uintptr(unsafe.Pointer(&result)), 0) + if res == 0 { + _ = err + return false + } + r := result.DwFlags&HCF_HIGHCONTRASTON == HCF_HIGHCONTRASTON + return r +} From 9d6d90c3e488557bd914b5ad27d6840f0996395c Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 8 Oct 2022 13:32:02 +1100 Subject: [PATCH 33/48] Add transparency methods --- v2/internal/platform/systray/windows.go | 6 ++- v2/internal/platform/win32/consts.go | 63 +++++++++++++------------ v2/internal/platform/win32/theme.go | 60 +++++++++++++++++++++++ 3 files changed, 98 insertions(+), 31 deletions(-) diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go index 3fec9a59f..965b08d54 100644 --- a/v2/internal/platform/systray/windows.go +++ b/v2/internal/platform/systray/windows.go @@ -26,6 +26,7 @@ var ( type Systray struct { id uint32 + mhwnd win32.HWND // main window handle hwnd win32.HWND hinst win32.HINSTANCE lclick func() @@ -70,7 +71,7 @@ func New() (*Systray, error) { MainClassName := "WailsSystray" ni.hinst, _ = RegisterWindow(MainClassName, ni.WinProc) - mhwnd := win32.CreateWindowEx( + ni.mhwnd = win32.CreateWindowEx( win32.WS_EX_CONTROLPARENT, win32.MustStringToUTF16Ptr(MainClassName), win32.MustStringToUTF16Ptr(""), @@ -84,7 +85,7 @@ func New() (*Systray, error) { 0, unsafe.Pointer(nil)) - if mhwnd == 0 { + if ni.mhwnd == 0 { return nil, errors.New("create main win failed") } @@ -296,6 +297,7 @@ func (p *Systray) WinProc(hwnd win32.HWND, msg uint32, wparam, lparam uintptr) u default: p.menu.ProcessCommand(cmdMsgID) } + } result, _, _ := DefWindowProc.Call(uintptr(hwnd), uintptr(msg), wparam, lparam) diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go index d9055e240..9b2629063 100644 --- a/v2/internal/platform/win32/consts.go +++ b/v2/internal/platform/win32/consts.go @@ -11,26 +11,27 @@ var ( modKernel32 = syscall.NewLazyDLL("kernel32.dll") procGetModuleHandle = modKernel32.NewProc("GetModuleHandleW") - moduser32 = syscall.NewLazyDLL("user32.dll") - procRegisterClassEx = moduser32.NewProc("RegisterClassExW") - procLoadIcon = moduser32.NewProc("LoadIconW") - procLoadCursor = moduser32.NewProc("LoadCursorW") - procCreateWindowEx = moduser32.NewProc("CreateWindowExW") - procPostMessage = moduser32.NewProc("PostMessageW") - procGetCursorPos = moduser32.NewProc("GetCursorPos") - procSetForegroundWindow = moduser32.NewProc("SetForegroundWindow") - procCreatePopupMenu = moduser32.NewProc("CreatePopupMenu") - procTrackPopupMenu = moduser32.NewProc("TrackPopupMenu") - procDestroyMenu = moduser32.NewProc("DestroyMenu") - procAppendMenuW = moduser32.NewProc("AppendMenuW") - procCheckMenuItem = moduser32.NewProc("CheckMenuItem") - procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx") - procGetMessageW = moduser32.NewProc("GetMessageW") - procIsDialogMessage = moduser32.NewProc("IsDialogMessageW") - procTranslateMessage = moduser32.NewProc("TranslateMessage") - procDispatchMessage = moduser32.NewProc("DispatchMessageW") - procPostQuitMessage = moduser32.NewProc("PostQuitMessage") - procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") + moduser32 = syscall.NewLazyDLL("user32.dll") + procRegisterClassEx = moduser32.NewProc("RegisterClassExW") + procLoadIcon = moduser32.NewProc("LoadIconW") + procLoadCursor = moduser32.NewProc("LoadCursorW") + procCreateWindowEx = moduser32.NewProc("CreateWindowExW") + procPostMessage = moduser32.NewProc("PostMessageW") + procGetCursorPos = moduser32.NewProc("GetCursorPos") + procSetForegroundWindow = moduser32.NewProc("SetForegroundWindow") + procCreatePopupMenu = moduser32.NewProc("CreatePopupMenu") + procTrackPopupMenu = moduser32.NewProc("TrackPopupMenu") + procDestroyMenu = moduser32.NewProc("DestroyMenu") + procAppendMenuW = moduser32.NewProc("AppendMenuW") + procCheckMenuItem = moduser32.NewProc("CheckMenuItem") + procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx") + procGetMessageW = moduser32.NewProc("GetMessageW") + procIsDialogMessage = moduser32.NewProc("IsDialogMessageW") + procTranslateMessage = moduser32.NewProc("TranslateMessage") + procDispatchMessage = moduser32.NewProc("DispatchMessageW") + procPostQuitMessage = moduser32.NewProc("PostQuitMessage") + procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") + procSetWindowCompositionAttribute = moduser32.NewProc("SetWindowCompositionAttribute") modshell32 = syscall.NewLazyDLL("shell32.dll") procShellNotifyIcon = modshell32.NewProc("Shell_NotifyIconW") @@ -104,15 +105,18 @@ func init() { } type HANDLE uintptr -type HINSTANCE HANDLE -type HICON HANDLE -type HCURSOR HANDLE -type HBRUSH HANDLE -type HWND HANDLE -type HMENU HANDLE +type HINSTANCE = HANDLE +type HICON = HANDLE +type HCURSOR = HANDLE +type HBRUSH = HANDLE +type HWND = HANDLE +type HMENU = HANDLE +type DWORD = uint32 type ATOM uint16 const ( + WM_ACTIVATE = 0x0006 + WM_ACTIVATEAPP = 0x001C WM_LBUTTONUP = 0x0202 WM_LBUTTONDBLCLK = 0x0203 WM_RBUTTONUP = 0x0205 @@ -120,9 +124,10 @@ const ( WM_TRAYICON = WM_USER + 69 WM_SETTINGCHANGE = 0x001A - WS_EX_APPWINDOW = 0x00040000 - WS_OVERLAPPEDWINDOW = 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000 - CW_USEDEFAULT = 0x80000000 + WS_EX_APPWINDOW = 0x00040000 + WS_OVERLAPPEDWINDOW = 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000 + WS_EX_NOREDIRECTIONBITMAP = 0x00200000 + CW_USEDEFAULT = 0x80000000 NIM_ADD = 0x00000000 NIM_MODIFY = 0x00000001 diff --git a/v2/internal/platform/win32/theme.go b/v2/internal/platform/win32/theme.go index c15d73a3a..6afb0ba67 100644 --- a/v2/internal/platform/win32/theme.go +++ b/v2/internal/platform/win32/theme.go @@ -16,10 +16,46 @@ const DwmwaSystemBackdropType DWMWINDOWATTRIBUTE = 38 const SPI_GETHIGHCONTRAST = 0x0042 const HCF_HIGHCONTRASTON = 0x00000001 +const WCA_ACCENT_POLICY WINDOWCOMPOSITIONATTRIB = 19 + +type ACCENT_STATE DWORD + +const ( + ACCENT_DISABLED ACCENT_STATE = 0 + ACCENT_ENABLE_GRADIENT ACCENT_STATE = 1 + ACCENT_ENABLE_TRANSPARENTGRADIENT ACCENT_STATE = 2 + ACCENT_ENABLE_BLURBEHIND ACCENT_STATE = 3 + ACCENT_ENABLE_ACRYLICBLURBEHIND ACCENT_STATE = 4 // RS4 1803 + ACCENT_ENABLE_HOSTBACKDROP ACCENT_STATE = 5 // RS5 1809 + ACCENT_INVALID_STATE ACCENT_STATE = 6 +) + +type ACCENT_POLICY struct { + AccentState ACCENT_STATE + AccentFlags DWORD + GradientColor DWORD + AnimationId DWORD +} + +type WINDOWCOMPOSITIONATTRIBDATA struct { + Attrib WINDOWCOMPOSITIONATTRIB + PvData unsafe.Pointer + CbData uintptr +} + +type WINDOWCOMPOSITIONATTRIB DWORD // BackdropType defines the type of translucency we wish to use type BackdropType int32 +const ( + BackdropTypeAuto BackdropType = 0 + BackdropTypeNone BackdropType = 1 + BackdropTypeMica BackdropType = 2 + BackdropTypeAcrylic BackdropType = 3 + BackdropTypeTabbed BackdropType = 4 +) + func dwmSetWindowAttribute(hwnd HWND, dwAttribute DWMWINDOWATTRIBUTE, pvAttribute unsafe.Pointer, cbAttribute uintptr) { ret, _, err := procDwmSetWindowAttribute.Call( uintptr(hwnd), @@ -63,6 +99,30 @@ func SetTheme(hwnd HWND, useDarkMode bool) { } } +func EnableBlurBehind(hwnd HWND) { + var accent = ACCENT_POLICY{ + AccentState: ACCENT_ENABLE_ACRYLICBLURBEHIND, + AccentFlags: 0x2, + } + var data WINDOWCOMPOSITIONATTRIBDATA + data.Attrib = WCA_ACCENT_POLICY + data.PvData = unsafe.Pointer(&accent) + data.CbData = unsafe.Sizeof(accent) + + SetWindowCompositionAttribute(hwnd, &data) +} + +func SetWindowCompositionAttribute(hwnd HWND, data *WINDOWCOMPOSITIONATTRIBDATA) bool { + if procSetWindowCompositionAttribute != nil { + ret, _, _ := procSetWindowCompositionAttribute.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(data)), + ) + return ret != 0 + } + return false +} + func EnableTranslucency(hwnd HWND, backdrop BackdropType) { if SupportsBackdropTypes() { dwmSetWindowAttribute(hwnd, DwmwaSystemBackdropType, unsafe.Pointer(&backdrop), unsafe.Sizeof(backdrop)) From c38e0ea84b942279c48b6b67705b73e8f0d58d98 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 9 Oct 2022 12:26:05 +1100 Subject: [PATCH 34/48] Use MenuManager for processing and handling menu state changes --- v2/internal/platform/menu/manager.go | 145 +++++++++++ v2/internal/platform/menu/manager_test.go | 295 ++++++++++++++++++++++ v2/internal/platform/systray/menu.go | 25 +- v2/pkg/menu/menuitem.go | 4 +- 4 files changed, 455 insertions(+), 14 deletions(-) create mode 100644 v2/internal/platform/menu/manager.go create mode 100644 v2/internal/platform/menu/manager_test.go diff --git a/v2/internal/platform/menu/manager.go b/v2/internal/platform/menu/manager.go new file mode 100644 index 000000000..28050294f --- /dev/null +++ b/v2/internal/platform/menu/manager.go @@ -0,0 +1,145 @@ +package menu + +import ( + "github.com/wailsapp/wails/v2/pkg/menu" +) + +// MenuManager manages the menus for the application +var MenuManager = NewManager() + +type radioGroup []*menu.MenuItem + +// Click updates the radio group state based on the item clicked +func (g *radioGroup) Click(item *menu.MenuItem) { + for _, radioGroupItem := range *g { + if radioGroupItem != item { + radioGroupItem.Checked = false + } + } +} + +type processedMenu struct { + + // the menu we processed + menu *menu.Menu + + // updateMenuItemCallback is called when the menu item needs to be updated in the UI + updateMenuItemCallback func(*menu.MenuItem) + + // items is a map of all menu items in this menu + items map[*menu.MenuItem]struct{} + + // radioGroups tracks which radiogroup a menu item belongs to + radioGroups map[*menu.MenuItem][]*radioGroup +} + +func newProcessedMenu(topLevelMenu *menu.Menu, updateMenuItemCallback func(*menu.MenuItem)) *processedMenu { + result := &processedMenu{ + updateMenuItemCallback: updateMenuItemCallback, + menu: topLevelMenu, + items: make(map[*menu.MenuItem]struct{}), + radioGroups: make(map[*menu.MenuItem][]*radioGroup), + } + result.process(topLevelMenu.Items) + return result +} + +func (p *processedMenu) process(items []*menu.MenuItem) { + var currentRadioGroup radioGroup + for index, item := range items { + // Save the reference to the top level menu for this item + p.items[item] = struct{}{} + + // If this is a radio item, add it to the radio group + if item.Type == menu.RadioType { + currentRadioGroup = append(currentRadioGroup, item) + } + + // If this is not a radio item, or we are processing the last item in the menu, + // then we need to add the current radio group to the map if it has items + if item.Type != menu.RadioType || index == len(items)-1 { + if len(currentRadioGroup) > 0 { + p.addRadioGroup(currentRadioGroup) + currentRadioGroup = nil + } + } + + // Process the submenu + if item.SubMenu != nil { + p.process(item.SubMenu.Items) + } + } +} + +func (p *processedMenu) processClick(item *menu.MenuItem) { + // If this item is not in our menu, then we can't process it + if _, ok := p.items[item]; !ok { + return + } + + // If this is a radio item, then we need to update the radio group + if item.Type == menu.RadioType { + // Get the radio groups for this item + radioGroups := p.radioGroups[item] + // Iterate each radio group this item belongs to and set the checked state + // of all items apart from the one that was clicked to false + for _, thisRadioGroup := range radioGroups { + thisRadioGroup.Click(item) + for _, thisRadioGroupItem := range *thisRadioGroup { + p.updateMenuItemCallback(thisRadioGroupItem) + } + } + } + + if item.Type == menu.CheckboxType { + p.updateMenuItemCallback(item) + } + +} + +func (p *processedMenu) addRadioGroup(r radioGroup) { + for _, item := range r { + p.radioGroups[item] = append(p.radioGroups[item], &r) + } +} + +type Manager struct { + menus map[*menu.Menu]*processedMenu +} + +func NewManager() *Manager { + return &Manager{ + menus: make(map[*menu.Menu]*processedMenu), + } +} + +func (m *Manager) AddMenu(menu *menu.Menu, updateMenuItemCallback func(*menu.MenuItem)) { + m.menus[menu] = newProcessedMenu(menu, updateMenuItemCallback) +} + +func (m *Manager) ProcessClick(item *menu.MenuItem) { + + // if menuitem is a checkbox, then we need to toggle the state + if item.Type == menu.CheckboxType { + item.Checked = !item.Checked + } + + // Set the radio item to checked + if item.Type == menu.RadioType { + item.Checked = true + } + + for _, thisMenu := range m.menus { + thisMenu.processClick(item) + } + + if item.Click != nil { + item.Click(&menu.CallbackData{ + MenuItem: item, + }) + } +} + +func (m *Manager) RemoveMenu(data *menu.Menu) { + delete(m.menus, data) +} diff --git a/v2/internal/platform/menu/manager_test.go b/v2/internal/platform/menu/manager_test.go new file mode 100644 index 000000000..ed7f98881 --- /dev/null +++ b/v2/internal/platform/menu/manager_test.go @@ -0,0 +1,295 @@ +package menu_test + +import ( + "github.com/stretchr/testify/require" + platformMenu "github.com/wailsapp/wails/v2/internal/platform/menu" + "github.com/wailsapp/wails/v2/pkg/menu" + "testing" +) + +func TestManager_ProcessClick_Checkbox(t *testing.T) { + + checkbox := menu.Label("Checkbox").SetChecked(false) + menu1 := &menu.Menu{ + Items: []*menu.MenuItem{ + checkbox, + }, + } + menu2 := &menu.Menu{ + Items: []*menu.MenuItem{ + checkbox, + }, + } + menuWithNoCheckbox := &menu.Menu{ + Items: []*menu.MenuItem{ + menu.Label("No Checkbox"), + }, + } + clicked := false + + tests := []struct { + name string + inputs []*menu.Menu + startState bool + expectedState bool + expectedMenuUpdates map[*menu.Menu][]*menu.MenuItem + click func(*menu.CallbackData) + }{ + { + name: "should callback menu checkbox state when clicked (false -> true)", + inputs: []*menu.Menu{menu1}, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + menu1: {checkbox}, + }, + startState: false, + expectedState: true, + }, + { + name: "should callback multiple menus when checkbox state when clicked (false -> true)", + inputs: []*menu.Menu{menu1, menu2}, + startState: false, + expectedState: true, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + menu1: {checkbox}, + menu2: {checkbox}, + }, + }, + { + name: "should callback only for the menus that the checkbox is in (false -> true)", + inputs: []*menu.Menu{menu1, menuWithNoCheckbox}, + startState: false, + expectedState: true, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + menu1: {checkbox}, + }, + }, + { + name: "should callback menu checkbox state when clicked (true->false)", + inputs: []*menu.Menu{menu1}, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + menu1: {checkbox}, + }, + startState: true, + expectedState: false, + }, + { + name: "should callback multiple menus when checkbox state when clicked (true->false)", + inputs: []*menu.Menu{menu1, menu2}, + startState: true, + expectedState: false, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + menu1: {checkbox}, + menu2: {checkbox}, + }, + }, + { + name: "should callback only for the menus that the checkbox is in (true->false)", + inputs: []*menu.Menu{menu1, menuWithNoCheckbox}, + startState: true, + expectedState: false, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + menu1: {checkbox}, + }, + }, + { + name: "should callback no menus if checkbox not in them", + inputs: []*menu.Menu{menuWithNoCheckbox}, + startState: false, + expectedState: false, + expectedMenuUpdates: nil, + }, + { + name: "should call Click on the checkbox", + inputs: []*menu.Menu{menu1, menu2}, + startState: false, + expectedState: true, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + menu1: {checkbox}, + menu2: {checkbox}, + }, + click: func(data *menu.CallbackData) { + clicked = true + }, + }, + } + for _, tt := range tests { + + menusUpdated := map[*menu.Menu][]*menu.MenuItem{} + clicked = false + + var checkMenuItemStateInMenu func(menu *menu.Menu) + + checkMenuItemStateInMenu = func(menu *menu.Menu) { + for _, item := range menusUpdated[menu] { + if item == checkbox { + require.Equal(t, tt.expectedState, item.Checked) + } + if item.SubMenu != nil { + checkMenuItemStateInMenu(item.SubMenu) + } + } + } + + t.Run(tt.name, func(t *testing.T) { + m := platformMenu.NewManager() + checkbox.SetChecked(tt.startState) + checkbox.Click = tt.click + for _, thisMenu := range tt.inputs { + thisMenu := thisMenu + m.AddMenu(thisMenu, func(menuItem *menu.MenuItem) { + menusUpdated[thisMenu] = append(menusUpdated[thisMenu], menuItem) + }) + } + m.ProcessClick(checkbox) + + // Check the item has the correct state in all the menus + for thisMenu := range menusUpdated { + require.EqualValues(t, tt.expectedMenuUpdates[thisMenu], menusUpdated[thisMenu]) + } + + if tt.click != nil { + require.Equal(t, true, clicked) + } + }) + } +} + +func TestManager_ProcessClick_RadioGroups(t *testing.T) { + + radio1 := menu.Radio("Radio1", false, nil, nil) + radio2 := menu.Radio("Radio2", false, nil, nil) + radio3 := menu.Radio("Radio3", false, nil, nil) + radio4 := menu.Radio("Radio4", false, nil, nil) + radio5 := menu.Radio("Radio5", false, nil, nil) + radio6 := menu.Radio("Radio6", false, nil, nil) + + radioGroupOne := &menu.Menu{ + Items: []*menu.MenuItem{ + radio1, + radio2, + radio3, + }, + } + + radioGroupTwo := &menu.Menu{ + Items: []*menu.MenuItem{ + radio4, + radio5, + radio6, + }, + } + + radioGroupThree := &menu.Menu{ + Items: []*menu.MenuItem{ + radio1, + radio2, + radio3, + }, + } + + clicked := false + + tests := []struct { + name string + inputs []*menu.Menu + startState map[*menu.MenuItem]bool + selected *menu.MenuItem + expectedMenuUpdates map[*menu.Menu][]*menu.MenuItem + click func(*menu.CallbackData) + expectedState map[*menu.MenuItem]bool + }{ + { + name: "should only set the clicked radio item", + inputs: []*menu.Menu{radioGroupOne}, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + radioGroupOne: {radio1, radio2, radio3}, + }, + startState: map[*menu.MenuItem]bool{ + radio1: true, + radio2: false, + radio3: false, + }, + selected: radio2, + expectedState: map[*menu.MenuItem]bool{ + radio1: false, + radio2: true, + radio3: false, + }, + }, + { + name: "should not affect other radio groups or menus", + inputs: []*menu.Menu{radioGroupOne, radioGroupTwo}, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + radioGroupOne: {radio1, radio2, radio3}, + }, + startState: map[*menu.MenuItem]bool{ + radio1: true, + radio2: false, + radio3: false, + radio4: true, + radio5: false, + radio6: false, + }, + selected: radio2, + expectedState: map[*menu.MenuItem]bool{ + radio1: false, + radio2: true, + radio3: false, + radio4: true, + radio5: false, + radio6: false, + }, + }, + { + name: "menus with the same radio group should be updated", + inputs: []*menu.Menu{radioGroupOne, radioGroupThree}, + expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{ + radioGroupOne: {radio1, radio2, radio3}, + radioGroupThree: {radio1, radio2, radio3}, + }, + startState: map[*menu.MenuItem]bool{ + radio1: true, + radio2: false, + radio3: false, + }, + selected: radio2, + expectedState: map[*menu.MenuItem]bool{ + radio1: false, + radio2: true, + radio3: false, + }, + }, + } + for _, tt := range tests { + + menusUpdated := map[*menu.Menu][]*menu.MenuItem{} + clicked = false + + t.Run(tt.name, func(t *testing.T) { + m := platformMenu.NewManager() + + for item, value := range tt.startState { + item.SetChecked(value) + } + + tt.selected.Click = tt.click + for _, thisMenu := range tt.inputs { + thisMenu := thisMenu + m.AddMenu(thisMenu, func(menuItem *menu.MenuItem) { + menusUpdated[thisMenu] = append(menusUpdated[thisMenu], menuItem) + }) + } + m.ProcessClick(tt.selected) + require.Equal(t, tt.expectedMenuUpdates, menusUpdated) + + // Check the items have the correct state in all the menus + for item, expectedValue := range tt.expectedState { + require.Equal(t, expectedValue, item.Checked) + } + + if tt.click != nil { + require.Equal(t, true, clicked) + } + }) + } +} diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index 057d5bf37..e7fc5516d 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -2,6 +2,7 @@ package systray import ( "errors" + platformMenu "github.com/wailsapp/wails/v2/internal/platform/menu" "github.com/wailsapp/wails/v2/internal/platform/win32" "github.com/wailsapp/wails/v2/pkg/menu" ) @@ -62,6 +63,7 @@ func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, func (p *PopupMenu) Update() error { p.menu = win32.CreatePopupMenu() + p.menuMapping = make(map[int]*menu.MenuItem) return p.buildMenu(p.menu, p.menuData, win32.MenuItemMsgID) } @@ -69,10 +71,10 @@ func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) { result := &PopupMenu{ parent: parent, menuData: inputMenu, - menuMapping: make(map[int]*menu.MenuItem), checkboxItems: make(map[*menu.MenuItem][]int), } err := result.Update() + platformMenu.MenuManager.AddMenu(inputMenu, result.UpdateMenuItem) return result, err } @@ -99,20 +101,17 @@ func (p *PopupMenu) ShowAtCursor() error { func (p *PopupMenu) ProcessCommand(cmdMsgID int) { item := p.menuMapping[cmdMsgID] - if item != nil { - if item.Type == menu.CheckboxType { - item.Checked = !item.Checked - for _, menuID := range p.checkboxItems[item] { - p.menu.Check(uintptr(menuID), item.Checked) - } - // TODO: Check duplicate menu items - } - if item.Click != nil { - item.Click(&menu.CallbackData{MenuItem: item}) - } - } + platformMenu.MenuManager.ProcessClick(item) } func (p *PopupMenu) Destroy() { p.menu.Destroy() } + +func (p *PopupMenu) UpdateMenuItem(item *menu.MenuItem) { + if item.IsCheckbox() { + for _, itemID := range p.checkboxItems[item] { + p.menu.Check(uintptr(itemID), item.Checked) + } + } +} diff --git a/v2/pkg/menu/menuitem.go b/v2/pkg/menu/menuitem.go index 013eb6bf2..d186a37b2 100644 --- a/v2/pkg/menu/menuitem.go +++ b/v2/pkg/menu/menuitem.go @@ -253,7 +253,9 @@ func (m *MenuItem) SetAccelerator(acc *keys.Accelerator) *MenuItem { func (m *MenuItem) SetChecked(value bool) *MenuItem { m.Checked = value - m.Type = CheckboxType + if m.Type != RadioType { + m.Type = CheckboxType + } return m } From 5adf8004ac336b268ebe61e83b41d573d3457fd3 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sun, 9 Oct 2022 20:09:31 +1100 Subject: [PATCH 35/48] Support Radio Groups --- v2/internal/platform/systray/menu.go | 86 ++++++++++++++++++++++++---- v2/internal/platform/win32/consts.go | 3 + v2/internal/platform/win32/menu.go | 14 +++++ v2/pkg/menu/menuitem.go | 4 ++ 4 files changed, 97 insertions(+), 10 deletions(-) diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index e7fc5516d..b74f7b17c 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -7,21 +7,53 @@ import ( "github.com/wailsapp/wails/v2/pkg/menu" ) +type RadioGroupMember struct { + ID int + MenuItem *menu.MenuItem +} + +type RadioGroup []*RadioGroupMember + +func (r *RadioGroup) Add(id int, item *menu.MenuItem) { + *r = append(*r, &RadioGroupMember{ + ID: id, + MenuItem: item, + }) +} + +func (r *RadioGroup) Bounds() (int, int) { + p := *r + return p[0].ID, p[len(p)-1].ID +} + +func (r *RadioGroup) MenuID(item *menu.MenuItem) int { + for _, member := range *r { + if member.MenuItem == item { + return member.ID + } + } + panic("RadioGroup.MenuID: item not found:") +} + type PopupMenu struct { menu win32.PopupMenu parent win32.HWND menuMapping map[int]*menu.MenuItem checkboxItems map[*menu.MenuItem][]int + radioGroups map[*menu.MenuItem][]*RadioGroup menuData *menu.Menu } func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, startindex int) error { + var currentRadioGroup RadioGroup for index, item := range inputMenu.Items { if item.Hidden { continue } var ret bool itemID := index + startindex + p.menuMapping[itemID] = item + flags := win32.MF_STRING if item.Disabled { flags = flags | win32.MF_GRAYED @@ -35,6 +67,22 @@ func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, if item.IsSeparator() { flags = flags | win32.MF_SEPARATOR } + + if item.IsCheckbox() { + p.checkboxItems[item] = append(p.checkboxItems[item], itemID) + } + if item.IsRadio() { + currentRadioGroup.Add(itemID, item) + } else { + if len(currentRadioGroup) > 0 { + for _, radioMember := range currentRadioGroup { + currentRadioGroup := currentRadioGroup + p.radioGroups[radioMember.MenuItem] = append(p.radioGroups[radioMember.MenuItem], ¤tRadioGroup) + } + currentRadioGroup = RadioGroup{} + } + } + if item.SubMenu != nil { flags = flags | win32.MF_POPUP submenu := win32.CreatePopupMenu() @@ -42,17 +90,9 @@ func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, if err != nil { return err } - ret = parentMenu.Append(uintptr(flags), uintptr(submenu), item.Label) - if ret == false { - return errors.New("AppendMenu failed") - } - continue + itemID = int(submenu) } - p.menuMapping[itemID] = item - if item.IsCheckbox() { - p.checkboxItems[item] = append(p.checkboxItems[item], itemID) - } ret = parentMenu.Append(uintptr(flags), uintptr(itemID), item.Label) if ret == false { return errors.New("AppendMenu failed") @@ -64,7 +104,12 @@ func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, func (p *PopupMenu) Update() error { p.menu = win32.CreatePopupMenu() p.menuMapping = make(map[int]*menu.MenuItem) - return p.buildMenu(p.menu, p.menuData, win32.MenuItemMsgID) + err := p.buildMenu(p.menu, p.menuData, win32.MenuItemMsgID) + if err != nil { + return err + } + p.updateRadioGroups() + return nil } func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) { @@ -72,6 +117,7 @@ func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) { parent: parent, menuData: inputMenu, checkboxItems: make(map[*menu.MenuItem][]int), + radioGroups: make(map[*menu.MenuItem][]*RadioGroup), } err := result.Update() platformMenu.MenuManager.AddMenu(inputMenu, result.UpdateMenuItem) @@ -113,5 +159,25 @@ func (p *PopupMenu) UpdateMenuItem(item *menu.MenuItem) { for _, itemID := range p.checkboxItems[item] { p.menu.Check(uintptr(itemID), item.Checked) } + return + } + if item.IsRadio() && item.Checked == true { + p.updateRadioGroup(item) + } +} + +func (p *PopupMenu) updateRadioGroups() { + for menuItem := range p.radioGroups { + if menuItem.Checked { + p.updateRadioGroup(menuItem) + } + } +} + +func (p *PopupMenu) updateRadioGroup(item *menu.MenuItem) { + for _, radioGroup := range p.radioGroups[item] { + thisMenuID := radioGroup.MenuID(item) + startID, endID := radioGroup.Bounds() + p.menu.CheckRadio(startID, endID, thisMenuID) } } diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go index 9b2629063..f34a0c5e2 100644 --- a/v2/internal/platform/win32/consts.go +++ b/v2/internal/platform/win32/consts.go @@ -24,6 +24,7 @@ var ( procDestroyMenu = moduser32.NewProc("DestroyMenu") procAppendMenuW = moduser32.NewProc("AppendMenuW") procCheckMenuItem = moduser32.NewProc("CheckMenuItem") + procCheckMenuRadioItem = moduser32.NewProc("CheckMenuRadioItem") procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx") procGetMessageW = moduser32.NewProc("GetMessageW") procIsDialogMessage = moduser32.NewProc("IsDialogMessageW") @@ -113,6 +114,7 @@ type HWND = HANDLE type HMENU = HANDLE type DWORD = uint32 type ATOM uint16 +type MenuID uint16 const ( WM_ACTIVATE = 0x0006 @@ -184,6 +186,7 @@ const ( MF_CHECKED = 0x00000008 MF_POPUP = 0x00000010 MF_MENUBARBREAK = 0x00000020 + MF_BYCOMMAND = 0x00000000 TPM_LEFTALIGN = 0x0000 WM_NULL = 0 diff --git a/v2/internal/platform/win32/menu.go b/v2/internal/platform/win32/menu.go index 56fb97b01..15c810be2 100644 --- a/v2/internal/platform/win32/menu.go +++ b/v2/internal/platform/win32/menu.go @@ -56,6 +56,16 @@ func (m Menu) Check(id uintptr, check bool) bool { return CheckMenuItem(HMENU(m), id, checkState) != 0 } +func (m Menu) CheckRadio(startID int, endID int, selectedID int) bool { + ret, _, _ := procCheckMenuRadioItem.Call( + uintptr(m), + uintptr(startID), + uintptr(endID), + uintptr(selectedID), + MF_BYCOMMAND) + return ret != 0 +} + func CheckMenuItem(menu HMENU, id uintptr, flags uint) uint { ret, _, _ := procCheckMenuItem.Call( uintptr(menu), @@ -64,3 +74,7 @@ func CheckMenuItem(menu HMENU, id uintptr, flags uint) uint { ) return uint(ret) } + +func (p PopupMenu) CheckRadio(startID, endID, selectedID int) bool { + return Menu(p).CheckRadio(startID, endID, selectedID) +} diff --git a/v2/pkg/menu/menuitem.go b/v2/pkg/menu/menuitem.go index d186a37b2..f6ea681d7 100644 --- a/v2/pkg/menu/menuitem.go +++ b/v2/pkg/menu/menuitem.go @@ -269,6 +269,10 @@ func (m *MenuItem) Show() *MenuItem { return m } +func (m *MenuItem) IsRadio() bool { + return m.Type == RadioType +} + func Label(label string) *MenuItem { return &MenuItem{ Type: TextType, From bd0e3b407ad7ca464c66743cde1fb25a6b3110c3 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 11 Oct 2022 19:43:22 +1100 Subject: [PATCH 36/48] Add accelerator code --- v2/go.mod | 2 +- v2/internal/platform/systray/menu.go | 37 +- v2/internal/platform/win32/consts.go | 13 + v2/internal/platform/win32/keyboard.go | 808 +++++++++++++++++++++++++ 4 files changed, 852 insertions(+), 8 deletions(-) create mode 100644 v2/internal/platform/win32/keyboard.go diff --git a/v2/go.mod b/v2/go.mod index b5533fcb9..3254d137e 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -44,6 +44,7 @@ require ( github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 github.com/samber/lo v1.27.1 github.com/stretchr/testify v1.7.1 + golang.org/x/image v0.0.0-20201208152932-35266b937fa6 ) require ( @@ -82,7 +83,6 @@ require ( github.com/yuin/goldmark-emoji v1.0.1 // indirect golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect - golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index b74f7b17c..5bcb55fef 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -2,6 +2,8 @@ package systray import ( "errors" + "fmt" + "github.com/samber/lo" platformMenu "github.com/wailsapp/wails/v2/internal/platform/menu" "github.com/wailsapp/wails/v2/internal/platform/win32" "github.com/wailsapp/wails/v2/pkg/menu" @@ -36,12 +38,14 @@ func (r *RadioGroup) MenuID(item *menu.MenuItem) int { } type PopupMenu struct { - menu win32.PopupMenu - parent win32.HWND - menuMapping map[int]*menu.MenuItem - checkboxItems map[*menu.MenuItem][]int - radioGroups map[*menu.MenuItem][]*RadioGroup - menuData *menu.Menu + menu win32.PopupMenu + parent win32.HWND + menuMapping map[int]*menu.MenuItem + checkboxItems map[*menu.MenuItem][]int + radioGroups map[*menu.MenuItem][]*RadioGroup + menuData *menu.Menu + shortcuts map[*menu.MenuItem]win32.Accelerator + acceleratorTable uintptr } func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, startindex int) error { @@ -93,7 +97,20 @@ func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, itemID = int(submenu) } - ret = parentMenu.Append(uintptr(flags), uintptr(itemID), item.Label) + var menuText = item.Label + if item.Accelerator != nil { + shortcut := win32.AcceleratorToShortcut(item.Accelerator) + menuText = fmt.Sprintf("%s\t%s", menuText, shortcut) + if _, exists := p.shortcuts[item]; !exists { + p.shortcuts[item] = win32.Accelerator{ + Virtual: byte(shortcut.Modifiers), + Key: uint16(shortcut.Key), + Cmd: uint16(itemID), + } + } + } + + ret = parentMenu.Append(uintptr(flags), uintptr(itemID), menuText) if ret == false { return errors.New("AppendMenu failed") } @@ -108,6 +125,7 @@ func (p *PopupMenu) Update() error { if err != nil { return err } + p.updateAccelerators() p.updateRadioGroups() return nil } @@ -118,6 +136,7 @@ func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) { menuData: inputMenu, checkboxItems: make(map[*menu.MenuItem][]int), radioGroups: make(map[*menu.MenuItem][]*RadioGroup), + shortcuts: make(map[*menu.MenuItem]win32.Accelerator), } err := result.Update() platformMenu.MenuManager.AddMenu(inputMenu, result.UpdateMenuItem) @@ -181,3 +200,7 @@ func (p *PopupMenu) updateRadioGroup(item *menu.MenuItem) { p.menu.CheckRadio(startID, endID, thisMenuID) } } + +func (p *PopupMenu) updateAccelerators() { + p.acceleratorTable = win32.CreateAcceleratorTable(lo.Values(p.shortcuts)) +} diff --git a/v2/internal/platform/win32/consts.go b/v2/internal/platform/win32/consts.go index f34a0c5e2..33eac939f 100644 --- a/v2/internal/platform/win32/consts.go +++ b/v2/internal/platform/win32/consts.go @@ -33,6 +33,9 @@ var ( procPostQuitMessage = moduser32.NewProc("PostQuitMessage") procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") procSetWindowCompositionAttribute = moduser32.NewProc("SetWindowCompositionAttribute") + procGetKeyState = moduser32.NewProc("GetKeyState") + procCreateAcceleratorTable = moduser32.NewProc("CreateAcceleratorTableW") + procTranslateAccelerator = moduser32.NewProc("TranslateAcceleratorW") modshell32 = syscall.NewLazyDLL("shell32.dll") procShellNotifyIcon = modshell32.NewProc("Shell_NotifyIconW") @@ -125,6 +128,11 @@ const ( WM_USER = 0x0400 WM_TRAYICON = WM_USER + 69 WM_SETTINGCHANGE = 0x001A + WM_KEYDOWN = 256 + WM_KEYUP = 257 + WM_SYSKEYDOWN = 260 + WM_SYSKEYUP = 261 + WM_MENUCHAR = 288 WS_EX_APPWINDOW = 0x00040000 WS_OVERLAPPEDWINDOW = 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000 @@ -173,6 +181,7 @@ const ( IDI_APPLICATION = 32512 WM_APP = 32768 WM_COMMAND = 273 + WM_SYSCOMMAND = 274 MenuItemMsgID = WM_APP + 1024 NotifyIconMessageId = WM_APP + iota @@ -248,3 +257,7 @@ func DispatchMessage(msg *MSG) uintptr { func PostQuitMessage(exitCode int32) { procPostQuitMessage.Call(uintptr(exitCode)) } + +func LoHiWords(input uint32) (uint16, uint16) { + return uint16(input & 0xffff), uint16(input >> 16 & 0xffff) +} diff --git a/v2/internal/platform/win32/keyboard.go b/v2/internal/platform/win32/keyboard.go new file mode 100644 index 000000000..6146da5f3 --- /dev/null +++ b/v2/internal/platform/win32/keyboard.go @@ -0,0 +1,808 @@ +/* + * Copyright (C) 2019 The Winc Authors. All Rights Reserved. + * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved. + */ + +package win32 + +import ( + "bytes" + "github.com/wailsapp/wails/v2/pkg/menu/keys" + "strings" + "unsafe" +) + +type Key uint16 + +func (k Key) String() string { + return key2string[k] +} + +// Virtual key codes +const ( + VK_LBUTTON = 1 + VK_RBUTTON = 2 + VK_CANCEL = 3 + VK_MBUTTON = 4 + VK_XBUTTON1 = 5 + VK_XBUTTON2 = 6 + VK_BACK = 8 + VK_TAB = 9 + VK_CLEAR = 12 + VK_RETURN = 13 + VK_SHIFT = 16 + VK_CONTROL = 17 + VK_MENU = 18 + VK_PAUSE = 19 + VK_CAPITAL = 20 + VK_KANA = 0x15 + VK_HANGEUL = 0x15 + VK_HANGUL = 0x15 + VK_JUNJA = 0x17 + VK_FINAL = 0x18 + VK_HANJA = 0x19 + VK_KANJI = 0x19 + VK_ESCAPE = 0x1B + VK_CONVERT = 0x1C + VK_NONCONVERT = 0x1D + VK_ACCEPT = 0x1E + VK_MODECHANGE = 0x1F + VK_SPACE = 32 + VK_PRIOR = 33 + VK_NEXT = 34 + VK_END = 35 + VK_HOME = 36 + VK_LEFT = 37 + VK_UP = 38 + VK_RIGHT = 39 + VK_DOWN = 40 + VK_SELECT = 41 + VK_PRINT = 42 + VK_EXECUTE = 43 + VK_SNAPSHOT = 44 + VK_INSERT = 45 + VK_DELETE = 46 + VK_HELP = 47 + VK_LWIN = 0x5B + VK_RWIN = 0x5C + VK_APPS = 0x5D + VK_SLEEP = 0x5F + VK_NUMPAD0 = 0x60 + VK_NUMPAD1 = 0x61 + VK_NUMPAD2 = 0x62 + VK_NUMPAD3 = 0x63 + VK_NUMPAD4 = 0x64 + VK_NUMPAD5 = 0x65 + VK_NUMPAD6 = 0x66 + VK_NUMPAD7 = 0x67 + VK_NUMPAD8 = 0x68 + VK_NUMPAD9 = 0x69 + VK_MULTIPLY = 0x6A + VK_ADD = 0x6B + VK_SEPARATOR = 0x6C + VK_SUBTRACT = 0x6D + VK_DECIMAL = 0x6E + VK_DIVIDE = 0x6F + VK_F1 = 0x70 + VK_F2 = 0x71 + VK_F3 = 0x72 + VK_F4 = 0x73 + VK_F5 = 0x74 + VK_F6 = 0x75 + VK_F7 = 0x76 + VK_F8 = 0x77 + VK_F9 = 0x78 + VK_F10 = 0x79 + VK_F11 = 0x7A + VK_F12 = 0x7B + VK_F13 = 0x7C + VK_F14 = 0x7D + VK_F15 = 0x7E + VK_F16 = 0x7F + VK_F17 = 0x80 + VK_F18 = 0x81 + VK_F19 = 0x82 + VK_F20 = 0x83 + VK_F21 = 0x84 + VK_F22 = 0x85 + VK_F23 = 0x86 + VK_F24 = 0x87 + VK_NUMLOCK = 0x90 + VK_SCROLL = 0x91 + VK_LSHIFT = 0xA0 + VK_RSHIFT = 0xA1 + VK_LCONTROL = 0xA2 + VK_RCONTROL = 0xA3 + VK_LMENU = 0xA4 + VK_RMENU = 0xA5 + VK_BROWSER_BACK = 0xA6 + VK_BROWSER_FORWARD = 0xA7 + VK_BROWSER_REFRESH = 0xA8 + VK_BROWSER_STOP = 0xA9 + VK_BROWSER_SEARCH = 0xAA + VK_BROWSER_FAVORITES = 0xAB + VK_BROWSER_HOME = 0xAC + VK_VOLUME_MUTE = 0xAD + VK_VOLUME_DOWN = 0xAE + VK_VOLUME_UP = 0xAF + VK_MEDIA_NEXT_TRACK = 0xB0 + VK_MEDIA_PREV_TRACK = 0xB1 + VK_MEDIA_STOP = 0xB2 + VK_MEDIA_PLAY_PAUSE = 0xB3 + VK_LAUNCH_MAIL = 0xB4 + VK_LAUNCH_MEDIA_SELECT = 0xB5 + VK_LAUNCH_APP1 = 0xB6 + VK_LAUNCH_APP2 = 0xB7 + VK_OEM_1 = 0xBA + VK_OEM_PLUS = 0xBB + VK_OEM_COMMA = 0xBC + VK_OEM_MINUS = 0xBD + VK_OEM_PERIOD = 0xBE + VK_OEM_2 = 0xBF + VK_OEM_3 = 0xC0 + VK_OEM_4 = 0xDB + VK_OEM_5 = 0xDC + VK_OEM_6 = 0xDD + VK_OEM_7 = 0xDE + VK_OEM_8 = 0xDF + VK_OEM_102 = 0xE2 + VK_PROCESSKEY = 0xE5 + VK_PACKET = 0xE7 + VK_ATTN = 0xF6 + VK_CRSEL = 0xF7 + VK_EXSEL = 0xF8 + VK_EREOF = 0xF9 + VK_PLAY = 0xFA + VK_ZOOM = 0xFB + VK_NONAME = 0xFC + VK_PA1 = 0xFD + VK_OEM_CLEAR = 0xFE +) + +const ( + KeyLButton Key = VK_LBUTTON + KeyRButton Key = VK_RBUTTON + KeyCancel Key = VK_CANCEL + KeyMButton Key = VK_MBUTTON + KeyXButton1 Key = VK_XBUTTON1 + KeyXButton2 Key = VK_XBUTTON2 + KeyBack Key = VK_BACK + KeyTab Key = VK_TAB + KeyClear Key = VK_CLEAR + KeyReturn Key = VK_RETURN + KeyShift Key = VK_SHIFT + KeyControl Key = VK_CONTROL + KeyAlt Key = VK_MENU + KeyMenu Key = VK_MENU + KeyPause Key = VK_PAUSE + KeyCapital Key = VK_CAPITAL + KeyKana Key = VK_KANA + KeyHangul Key = VK_HANGUL + KeyJunja Key = VK_JUNJA + KeyFinal Key = VK_FINAL + KeyHanja Key = VK_HANJA + KeyKanji Key = VK_KANJI + KeyEscape Key = VK_ESCAPE + KeyConvert Key = VK_CONVERT + KeyNonconvert Key = VK_NONCONVERT + KeyAccept Key = VK_ACCEPT + KeyModeChange Key = VK_MODECHANGE + KeySpace Key = VK_SPACE + KeyPrior Key = VK_PRIOR + KeyNext Key = VK_NEXT + KeyEnd Key = VK_END + KeyHome Key = VK_HOME + KeyLeft Key = VK_LEFT + KeyUp Key = VK_UP + KeyRight Key = VK_RIGHT + KeyDown Key = VK_DOWN + KeySelect Key = VK_SELECT + KeyPrint Key = VK_PRINT + KeyExecute Key = VK_EXECUTE + KeySnapshot Key = VK_SNAPSHOT + KeyInsert Key = VK_INSERT + KeyDelete Key = VK_DELETE + KeyHelp Key = VK_HELP + Key0 Key = 0x30 + Key1 Key = 0x31 + Key2 Key = 0x32 + Key3 Key = 0x33 + Key4 Key = 0x34 + Key5 Key = 0x35 + Key6 Key = 0x36 + Key7 Key = 0x37 + Key8 Key = 0x38 + Key9 Key = 0x39 + KeyA Key = 0x41 + KeyB Key = 0x42 + KeyC Key = 0x43 + KeyD Key = 0x44 + KeyE Key = 0x45 + KeyF Key = 0x46 + KeyG Key = 0x47 + KeyH Key = 0x48 + KeyI Key = 0x49 + KeyJ Key = 0x4A + KeyK Key = 0x4B + KeyL Key = 0x4C + KeyM Key = 0x4D + KeyN Key = 0x4E + KeyO Key = 0x4F + KeyP Key = 0x50 + KeyQ Key = 0x51 + KeyR Key = 0x52 + KeyS Key = 0x53 + KeyT Key = 0x54 + KeyU Key = 0x55 + KeyV Key = 0x56 + KeyW Key = 0x57 + KeyX Key = 0x58 + KeyY Key = 0x59 + KeyZ Key = 0x5A + KeyLWIN Key = VK_LWIN + KeyRWIN Key = VK_RWIN + KeyApps Key = VK_APPS + KeySleep Key = VK_SLEEP + KeyNumpad0 Key = VK_NUMPAD0 + KeyNumpad1 Key = VK_NUMPAD1 + KeyNumpad2 Key = VK_NUMPAD2 + KeyNumpad3 Key = VK_NUMPAD3 + KeyNumpad4 Key = VK_NUMPAD4 + KeyNumpad5 Key = VK_NUMPAD5 + KeyNumpad6 Key = VK_NUMPAD6 + KeyNumpad7 Key = VK_NUMPAD7 + KeyNumpad8 Key = VK_NUMPAD8 + KeyNumpad9 Key = VK_NUMPAD9 + KeyMultiply Key = VK_MULTIPLY + KeyAdd Key = VK_ADD + KeySeparator Key = VK_SEPARATOR + KeySubtract Key = VK_SUBTRACT + KeyDecimal Key = VK_DECIMAL + KeyDivide Key = VK_DIVIDE + KeyF1 Key = VK_F1 + KeyF2 Key = VK_F2 + KeyF3 Key = VK_F3 + KeyF4 Key = VK_F4 + KeyF5 Key = VK_F5 + KeyF6 Key = VK_F6 + KeyF7 Key = VK_F7 + KeyF8 Key = VK_F8 + KeyF9 Key = VK_F9 + KeyF10 Key = VK_F10 + KeyF11 Key = VK_F11 + KeyF12 Key = VK_F12 + KeyF13 Key = VK_F13 + KeyF14 Key = VK_F14 + KeyF15 Key = VK_F15 + KeyF16 Key = VK_F16 + KeyF17 Key = VK_F17 + KeyF18 Key = VK_F18 + KeyF19 Key = VK_F19 + KeyF20 Key = VK_F20 + KeyF21 Key = VK_F21 + KeyF22 Key = VK_F22 + KeyF23 Key = VK_F23 + KeyF24 Key = VK_F24 + KeyNumlock Key = VK_NUMLOCK + KeyScroll Key = VK_SCROLL + KeyLShift Key = VK_LSHIFT + KeyRShift Key = VK_RSHIFT + KeyLControl Key = VK_LCONTROL + KeyRControl Key = VK_RCONTROL + KeyLAlt Key = VK_LMENU + KeyLMenu Key = VK_LMENU + KeyRAlt Key = VK_RMENU + KeyRMenu Key = VK_RMENU + KeyBrowserBack Key = VK_BROWSER_BACK + KeyBrowserForward Key = VK_BROWSER_FORWARD + KeyBrowserRefresh Key = VK_BROWSER_REFRESH + KeyBrowserStop Key = VK_BROWSER_STOP + KeyBrowserSearch Key = VK_BROWSER_SEARCH + KeyBrowserFavorites Key = VK_BROWSER_FAVORITES + KeyBrowserHome Key = VK_BROWSER_HOME + KeyVolumeMute Key = VK_VOLUME_MUTE + KeyVolumeDown Key = VK_VOLUME_DOWN + KeyVolumeUp Key = VK_VOLUME_UP + KeyMediaNextTrack Key = VK_MEDIA_NEXT_TRACK + KeyMediaPrevTrack Key = VK_MEDIA_PREV_TRACK + KeyMediaStop Key = VK_MEDIA_STOP + KeyMediaPlayPause Key = VK_MEDIA_PLAY_PAUSE + KeyLaunchMail Key = VK_LAUNCH_MAIL + KeyLaunchMediaSelect Key = VK_LAUNCH_MEDIA_SELECT + KeyLaunchApp1 Key = VK_LAUNCH_APP1 + KeyLaunchApp2 Key = VK_LAUNCH_APP2 + KeyOEM1 Key = VK_OEM_1 + KeyOEMPlus Key = VK_OEM_PLUS + KeyOEMComma Key = VK_OEM_COMMA + KeyOEMMinus Key = VK_OEM_MINUS + KeyOEMPeriod Key = VK_OEM_PERIOD + KeyOEM2 Key = VK_OEM_2 + KeyOEM3 Key = VK_OEM_3 + KeyOEM4 Key = VK_OEM_4 + KeyOEM5 Key = VK_OEM_5 + KeyOEM6 Key = VK_OEM_6 + KeyOEM7 Key = VK_OEM_7 + KeyOEM8 Key = VK_OEM_8 + KeyOEM102 Key = VK_OEM_102 + KeyProcessKey Key = VK_PROCESSKEY + KeyPacket Key = VK_PACKET + KeyAttn Key = VK_ATTN + KeyCRSel Key = VK_CRSEL + KeyEXSel Key = VK_EXSEL + KeyErEOF Key = VK_EREOF + KeyPlay Key = VK_PLAY + KeyZoom Key = VK_ZOOM + KeyNoName Key = VK_NONAME + KeyPA1 Key = VK_PA1 + KeyOEMClear Key = VK_OEM_CLEAR +) + +var key2string = map[Key]string{ + KeyLButton: "LButton", + KeyRButton: "RButton", + KeyCancel: "Cancel", + KeyMButton: "MButton", + KeyXButton1: "XButton1", + KeyXButton2: "XButton2", + KeyBack: "Back", + KeyTab: "Tab", + KeyClear: "Clear", + KeyReturn: "Return", + KeyShift: "Shift", + KeyControl: "Control", + KeyAlt: "Alt / Menu", + KeyPause: "Pause", + KeyCapital: "Capital", + KeyKana: "Kana / Hangul", + KeyJunja: "Junja", + KeyFinal: "Final", + KeyHanja: "Hanja / Kanji", + KeyEscape: "Escape", + KeyConvert: "Convert", + KeyNonconvert: "Nonconvert", + KeyAccept: "Accept", + KeyModeChange: "ModeChange", + KeySpace: "Space", + KeyPrior: "Prior", + KeyNext: "Next", + KeyEnd: "End", + KeyHome: "Home", + KeyLeft: "Left", + KeyUp: "Up", + KeyRight: "Right", + KeyDown: "Down", + KeySelect: "Select", + KeyPrint: "Print", + KeyExecute: "Execute", + KeySnapshot: "Snapshot", + KeyInsert: "Insert", + KeyDelete: "Delete", + KeyHelp: "Help", + Key0: "0", + Key1: "1", + Key2: "2", + Key3: "3", + Key4: "4", + Key5: "5", + Key6: "6", + Key7: "7", + Key8: "8", + Key9: "9", + KeyA: "A", + KeyB: "B", + KeyC: "C", + KeyD: "D", + KeyE: "E", + KeyF: "F", + KeyG: "G", + KeyH: "H", + KeyI: "I", + KeyJ: "J", + KeyK: "K", + KeyL: "L", + KeyM: "M", + KeyN: "N", + KeyO: "O", + KeyP: "P", + KeyQ: "Q", + KeyR: "R", + KeyS: "S", + KeyT: "T", + KeyU: "U", + KeyV: "V", + KeyW: "W", + KeyX: "X", + KeyY: "Y", + KeyZ: "Z", + KeyLWIN: "LWIN", + KeyRWIN: "RWIN", + KeyApps: "Apps", + KeySleep: "Sleep", + KeyNumpad0: "Numpad0", + KeyNumpad1: "Numpad1", + KeyNumpad2: "Numpad2", + KeyNumpad3: "Numpad3", + KeyNumpad4: "Numpad4", + KeyNumpad5: "Numpad5", + KeyNumpad6: "Numpad6", + KeyNumpad7: "Numpad7", + KeyNumpad8: "Numpad8", + KeyNumpad9: "Numpad9", + KeyMultiply: "Multiply", + KeyAdd: "Add", + KeySeparator: "Separator", + KeySubtract: "Subtract", + KeyDecimal: "Decimal", + KeyDivide: "Divide", + KeyF1: "F1", + KeyF2: "F2", + KeyF3: "F3", + KeyF4: "F4", + KeyF5: "F5", + KeyF6: "F6", + KeyF7: "F7", + KeyF8: "F8", + KeyF9: "F9", + KeyF10: "F10", + KeyF11: "F11", + KeyF12: "F12", + KeyF13: "F13", + KeyF14: "F14", + KeyF15: "F15", + KeyF16: "F16", + KeyF17: "F17", + KeyF18: "F18", + KeyF19: "F19", + KeyF20: "F20", + KeyF21: "F21", + KeyF22: "F22", + KeyF23: "F23", + KeyF24: "F24", + KeyNumlock: "Numlock", + KeyScroll: "Scroll", + KeyLShift: "LShift", + KeyRShift: "RShift", + KeyLControl: "LControl", + KeyRControl: "RControl", + KeyLMenu: "LMenu", + KeyRMenu: "RMenu", + KeyBrowserBack: "BrowserBack", + KeyBrowserForward: "BrowserForward", + KeyBrowserRefresh: "BrowserRefresh", + KeyBrowserStop: "BrowserStop", + KeyBrowserSearch: "BrowserSearch", + KeyBrowserFavorites: "BrowserFavorites", + KeyBrowserHome: "BrowserHome", + KeyVolumeMute: "VolumeMute", + KeyVolumeDown: "VolumeDown", + KeyVolumeUp: "VolumeUp", + KeyMediaNextTrack: "MediaNextTrack", + KeyMediaPrevTrack: "MediaPrevTrack", + KeyMediaStop: "MediaStop", + KeyMediaPlayPause: "MediaPlayPause", + KeyLaunchMail: "LaunchMail", + KeyLaunchMediaSelect: "LaunchMediaSelect", + KeyLaunchApp1: "LaunchApp1", + KeyLaunchApp2: "LaunchApp2", + KeyOEM1: "OEM1", + KeyOEMPlus: "OEMPlus", + KeyOEMComma: "OEMComma", + KeyOEMMinus: "OEMMinus", + KeyOEMPeriod: "OEMPeriod", + KeyOEM2: "OEM2", + KeyOEM3: "OEM3", + KeyOEM4: "OEM4", + KeyOEM5: "OEM5", + KeyOEM6: "OEM6", + KeyOEM7: "OEM7", + KeyOEM8: "OEM8", + KeyOEM102: "OEM102", + KeyProcessKey: "ProcessKey", + KeyPacket: "Packet", + KeyAttn: "Attn", + KeyCRSel: "CRSel", + KeyEXSel: "EXSel", + KeyErEOF: "ErEOF", + KeyPlay: "Play", + KeyZoom: "Zoom", + KeyNoName: "NoName", + KeyPA1: "PA1", + KeyOEMClear: "OEMClear", +} + +type Modifiers byte + +func (m Modifiers) String() string { + return modifiers2string[m] +} + +var modifiers2string = map[Modifiers]string{ + ModShift: "Shift", + ModControl: "Ctrl", + ModControl | ModShift: "Ctrl+Shift", + ModAlt: "Alt", + ModAlt | ModShift: "Alt+Shift", + ModAlt | ModControl | ModShift: "Alt+Ctrl+Shift", +} + +const ( + ModShift Modifiers = 1 << iota + ModControl + ModAlt +) + +func ModifiersDown() Modifiers { + var m Modifiers + + if ShiftDown() { + m |= ModShift + } + if ControlDown() { + m |= ModControl + } + if AltDown() { + m |= ModAlt + } + + return m +} + +type Shortcut struct { + Modifiers Modifiers + Key Key +} + +func (s Shortcut) String() string { + m := s.Modifiers.String() + if m == "" { + return s.Key.String() + } + + b := new(bytes.Buffer) + + b.WriteString(m) + b.WriteRune('+') + b.WriteString(s.Key.String()) + + return b.String() +} + +func GetKeyState(nVirtKey int32) int16 { + ret, _, _ := procGetKeyState.Call( + uintptr(nVirtKey), + ) + + return int16(ret) +} + +func AltDown() bool { + return GetKeyState(int32(KeyAlt))>>15 != 0 +} + +func ControlDown() bool { + return GetKeyState(int32(KeyControl))>>15 != 0 +} + +func ShiftDown() bool { + return GetKeyState(int32(KeyShift))>>15 != 0 +} + +var ModifierMap = map[keys.Modifier]Modifiers{ + keys.ShiftKey: ModShift, + keys.ControlKey: ModControl, + keys.OptionOrAltKey: ModAlt, + keys.CmdOrCtrlKey: ModControl, +} + +var NoShortcut = Shortcut{} + +func AcceleratorToShortcut(accelerator *keys.Accelerator) Shortcut { + + if accelerator == nil { + return NoShortcut + } + inKey := strings.ToUpper(accelerator.Key) + key, exists := KeyMap[inKey] + if !exists { + return NoShortcut + } + var modifiers Modifiers + if _, exists := shiftMap[inKey]; exists { + modifiers = ModShift + } + for _, mod := range accelerator.Modifiers { + modifiers |= ModifierMap[mod] + } + return Shortcut{ + Modifiers: modifiers, + Key: key, + } +} + +var shiftMap = map[string]struct{}{ + "~": {}, + ")": {}, + "!": {}, + "@": {}, + "#": {}, + "$": {}, + "%": {}, + "^": {}, + "&": {}, + "*": {}, + "(": {}, + "_": {}, + "PLUS": {}, + "<": {}, + ">": {}, + "?": {}, + ":": {}, + `"`: {}, + "{": {}, + "}": {}, + "|": {}, +} + +var KeyMap = map[string]Key{ + "0": Key0, + "1": Key1, + "2": Key2, + "3": Key3, + "4": Key4, + "5": Key5, + "6": Key6, + "7": Key7, + "8": Key8, + "9": Key9, + "A": KeyA, + "B": KeyB, + "C": KeyC, + "D": KeyD, + "E": KeyE, + "F": KeyF, + "G": KeyG, + "H": KeyH, + "I": KeyI, + "J": KeyJ, + "K": KeyK, + "L": KeyL, + "M": KeyM, + "N": KeyN, + "O": KeyO, + "P": KeyP, + "Q": KeyQ, + "R": KeyR, + "S": KeyS, + "T": KeyT, + "U": KeyU, + "V": KeyV, + "W": KeyW, + "X": KeyX, + "Y": KeyY, + "Z": KeyZ, + "F1": KeyF1, + "F2": KeyF2, + "F3": KeyF3, + "F4": KeyF4, + "F5": KeyF5, + "F6": KeyF6, + "F7": KeyF7, + "F8": KeyF8, + "F9": KeyF9, + "F10": KeyF10, + "F11": KeyF11, + "F12": KeyF12, + "F13": KeyF13, + "F14": KeyF14, + "F15": KeyF15, + "F16": KeyF16, + "F17": KeyF17, + "F18": KeyF18, + "F19": KeyF19, + "F20": KeyF20, + "F21": KeyF21, + "F22": KeyF22, + "F23": KeyF23, + "F24": KeyF24, + + "`": KeyOEM3, + ",": KeyOEMComma, + ".": KeyOEMPeriod, + "/": KeyOEM2, + ";": KeyOEM1, + "'": KeyOEM7, + "[": KeyOEM4, + "]": KeyOEM6, + `\`: KeyOEM5, + "~": KeyOEM3, + ")": Key0, + "!": Key1, + "@": Key2, + "#": Key3, + "$": Key4, + "%": Key5, + "^": Key6, + "&": Key7, + "*": Key8, + "(": Key9, + "_": KeyOEMMinus, + "PLUS": KeyOEMPlus, + "<": KeyOEMComma, + ">": KeyOEMPeriod, + "?": KeyOEM2, + ":": KeyOEM1, + `"`: KeyOEM7, + "{": KeyOEM4, + "}": KeyOEM6, + "|": KeyOEM5, + + "SPACE": KeySpace, + "TAB": KeyTab, + "CAPSLOCK": KeyCapital, + "NUMLOCK": KeyNumlock, + "SCROLLLOCK": KeyScroll, + "BACKSPACE": KeyBack, + "DELETE": KeyDelete, + "INSERT": KeyInsert, + "RETURN": KeyReturn, + "ENTER": KeyReturn, + "UP": KeyUp, + "DOWN": KeyDown, + "LEFT": KeyLeft, + "RIGHT": KeyRight, + "HOME": KeyHome, + "END": KeyEnd, + "PAGEUP": KeyPrior, + "PAGEDOWN": KeyNext, + "ESCAPE": KeyEscape, + "ESC": KeyEscape, + "VOLUMEUP": KeyVolumeUp, + "VOLUMEDOWN": KeyVolumeDown, + "VOLUMEMUTE": KeyVolumeMute, + "MEDIANEXTTRACK": KeyMediaNextTrack, + "MEDIAPREVIOUSTRACK": KeyMediaPrevTrack, + "MEDIASTOP": KeyMediaStop, + "MEDIAPLAYPAUSE": KeyMediaPlayPause, + "PRINTSCREEN": KeyPrint, + "NUM0": KeyNumpad0, + "NUM1": KeyNumpad1, + "NUM2": KeyNumpad2, + "NUM3": KeyNumpad3, + "NUM4": KeyNumpad4, + "NUM5": KeyNumpad5, + "NUM6": KeyNumpad6, + "NUM7": KeyNumpad7, + "NUM8": KeyNumpad8, + "NUM9": KeyNumpad9, + "nummult": KeyMultiply, + "numadd": KeyAdd, + "numsub": KeySubtract, + "numdec": KeyDecimal, + "numdiv": KeyDivide, +} + +type Accelerator struct { + Virtual byte + Key uint16 + Cmd uint16 +} + +func CreateAcceleratorTable(acc []Accelerator) uintptr { + if len(acc) == 0 { + return 0 + } + ret, _, _ := procCreateAcceleratorTable.Call( + uintptr(unsafe.Pointer(&acc[0])), + uintptr(len(acc)), + ) + return ret +} + +func TranslateAccelerator(hwnd HWND, hAccTable uintptr, lpMsg *MSG) bool { + ret, _, _ := procTranslateAccelerator.Call( + uintptr(hwnd), + hAccTable, + uintptr(unsafe.Pointer(lpMsg)), + ) + return ret != 0 +} From bca58afc0424821eb1e1e1899815a33ba6f0cfa5 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 11 Oct 2022 19:45:43 +1100 Subject: [PATCH 37/48] Remove accelerator code, but leave text in menu --- v2/internal/platform/systray/menu.go | 30 ++++++++-------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/v2/internal/platform/systray/menu.go b/v2/internal/platform/systray/menu.go index 5bcb55fef..e41cef3f7 100644 --- a/v2/internal/platform/systray/menu.go +++ b/v2/internal/platform/systray/menu.go @@ -3,7 +3,6 @@ package systray import ( "errors" "fmt" - "github.com/samber/lo" platformMenu "github.com/wailsapp/wails/v2/internal/platform/menu" "github.com/wailsapp/wails/v2/internal/platform/win32" "github.com/wailsapp/wails/v2/pkg/menu" @@ -38,14 +37,12 @@ func (r *RadioGroup) MenuID(item *menu.MenuItem) int { } type PopupMenu struct { - menu win32.PopupMenu - parent win32.HWND - menuMapping map[int]*menu.MenuItem - checkboxItems map[*menu.MenuItem][]int - radioGroups map[*menu.MenuItem][]*RadioGroup - menuData *menu.Menu - shortcuts map[*menu.MenuItem]win32.Accelerator - acceleratorTable uintptr + menu win32.PopupMenu + parent win32.HWND + menuMapping map[int]*menu.MenuItem + checkboxItems map[*menu.MenuItem][]int + radioGroups map[*menu.MenuItem][]*RadioGroup + menuData *menu.Menu } func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, startindex int) error { @@ -101,13 +98,8 @@ func (p *PopupMenu) buildMenu(parentMenu win32.PopupMenu, inputMenu *menu.Menu, if item.Accelerator != nil { shortcut := win32.AcceleratorToShortcut(item.Accelerator) menuText = fmt.Sprintf("%s\t%s", menuText, shortcut) - if _, exists := p.shortcuts[item]; !exists { - p.shortcuts[item] = win32.Accelerator{ - Virtual: byte(shortcut.Modifiers), - Key: uint16(shortcut.Key), - Cmd: uint16(itemID), - } - } + // Popup Menus don't appear to support accelerators and I'm not + // sure they make sense either } ret = parentMenu.Append(uintptr(flags), uintptr(itemID), menuText) @@ -125,7 +117,6 @@ func (p *PopupMenu) Update() error { if err != nil { return err } - p.updateAccelerators() p.updateRadioGroups() return nil } @@ -136,7 +127,6 @@ func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) { menuData: inputMenu, checkboxItems: make(map[*menu.MenuItem][]int), radioGroups: make(map[*menu.MenuItem][]*RadioGroup), - shortcuts: make(map[*menu.MenuItem]win32.Accelerator), } err := result.Update() platformMenu.MenuManager.AddMenu(inputMenu, result.UpdateMenuItem) @@ -200,7 +190,3 @@ func (p *PopupMenu) updateRadioGroup(item *menu.MenuItem) { p.menu.CheckRadio(startID, endID, thisMenuID) } } - -func (p *PopupMenu) updateAccelerators() { - p.acceleratorTable = win32.CreateAcceleratorTable(lo.Values(p.shortcuts)) -} From 828ebd8fb695f04002e9f08b74140c35cbb6ceb0 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 11 Oct 2022 21:07:01 +1100 Subject: [PATCH 38/48] Support left/right click override --- v2/internal/platform/systray.go | 2 ++ v2/internal/platform/systray/windows.go | 40 ++++++++++++++----------- v2/pkg/application/systray.go | 6 ++++ v2/pkg/options/systemtray.go | 6 +++- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/v2/internal/platform/systray.go b/v2/internal/platform/systray.go index 9625f1a7e..611d74c48 100644 --- a/v2/internal/platform/systray.go +++ b/v2/internal/platform/systray.go @@ -18,6 +18,8 @@ type SysTray interface { SetMenu(menu *menu.Menu) error SetIcons(lightModeIcon, darkModeIcon *options.SystemTrayIcon) error Update() error + OnLeftClick(func()) + OnRightClick(func()) } func NewSysTray() SysTray { diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go index 965b08d54..032067a13 100644 --- a/v2/internal/platform/systray/windows.go +++ b/v2/internal/platform/systray/windows.go @@ -63,9 +63,17 @@ func (p *Systray) Update() error { func (p *Systray) SetTitle(_ string) {} func New() (*Systray, error) { - ni := &Systray{ - lclick: func() {}, - rclick: func() {}, + ni := &Systray{} + + ni.lclick = func() { + if ni.menu != nil { + _ = ni.menu.ShowAtCursor() + } + } + ni.rclick = func() { + if ni.menu != nil { + _ = ni.menu.ShowAtCursor() + } } MainClassName := "WailsSystray" @@ -158,12 +166,16 @@ func (p *Systray) Stop() error { return nil } -func (p *Systray) Click(fn func()) { - p.lclick = fn +func (p *Systray) OnLeftClick(fn func()) { + if fn != nil { + p.lclick = fn + } } func (p *Systray) OnRightClick(fn func()) { - p.rclick = fn + if fn != nil { + p.rclick = fn + } } func (p *Systray) SetTooltip(tooltip string) error { @@ -266,20 +278,12 @@ func (p *Systray) WinProc(hwnd win32.HWND, msg uint32, wparam, lparam uintptr) u switch msg { case win32.NotifyIconMessageId: if lparam == win32.WM_LBUTTONUP { - p.lclick() - if p.menu != nil { - err := p.menu.ShowAtCursor() - if err != nil { - return 0 - } + if p.lclick != nil { + p.lclick() } } else if lparam == win32.WM_RBUTTONUP { - p.rclick() - if p.menu != nil { - err := p.menu.ShowAtCursor() - if err != nil { - return 0 - } + if p.rclick != nil { + p.rclick() } } case win32.WM_SETTINGCHANGE: diff --git a/v2/pkg/application/systray.go b/v2/pkg/application/systray.go index 00965e41f..0447e27b9 100644 --- a/v2/pkg/application/systray.go +++ b/v2/pkg/application/systray.go @@ -15,6 +15,8 @@ type SystemTray struct { tooltip string startHidden bool menu *menu.Menu + onLeftClick func() + onRightClick func() // The platform specific implementation impl platform.SysTray @@ -28,6 +30,8 @@ func newSystemTray(options *options.SystemTray) *SystemTray { tooltip: options.Tooltip, startHidden: options.StartHidden, menu: options.Menu, + onLeftClick: options.OnLeftClick, + onRightClick: options.OnRightClick, } } @@ -36,6 +40,8 @@ func (t *SystemTray) run() { t.impl.SetTitle(t.title) t.impl.SetIcons(t.lightModeIcon, t.darkModeIcon) t.impl.SetTooltip(t.tooltip) + t.impl.OnLeftClick(t.onLeftClick) + t.impl.OnRightClick(t.onRightClick) if !t.startHidden { t.impl.Show() } diff --git a/v2/pkg/options/systemtray.go b/v2/pkg/options/systemtray.go index 14639040e..3e694ce85 100644 --- a/v2/pkg/options/systemtray.go +++ b/v2/pkg/options/systemtray.go @@ -1,6 +1,8 @@ package options -import "github.com/wailsapp/wails/v2/pkg/menu" +import ( + "github.com/wailsapp/wails/v2/pkg/menu" +) // SystemTray contains options for the system tray type SystemTray struct { @@ -10,6 +12,8 @@ type SystemTray struct { Tooltip string StartHidden bool Menu *menu.Menu + OnLeftClick func() + OnRightClick func() } // SystemTrayIcon represents a system tray icon From 2f99ef7c9448cd7b267db64b54bd2fb75dc97b52 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 11 Oct 2022 21:09:59 +1100 Subject: [PATCH 39/48] Add example --- v2/examples/README.md | 15 + v2/examples/common/fonts/OFL.txt | 93 ++ .../fonts/nunito-v16-latin-regular.woff2 | Bin 0 -> 18972 bytes v2/examples/common/images/logo-universal.png | Bin 0 -> 139695 bytes v2/examples/systray/.gitignore | 2 + v2/examples/systray/README.md | 17 + v2/examples/systray/build/appicon.png | Bin 0 -> 132625 bytes v2/examples/systray/build/darwin/Info.plist | 14 + v2/examples/systray/build/windows/icon.ico | Bin 0 -> 21017 bytes v2/examples/systray/build/windows/info.json | 15 + .../build/windows/installer/project.nsi | 101 +++ .../build/windows/installer/wails_tools.nsh | 171 ++++ .../systray/build/windows/wails.exe.manifest | 15 + v2/examples/systray/frontend/dist/.gitkeep | 0 v2/examples/systray/frontend/index.html | 59 ++ .../systray/frontend/package-lock.json | 852 ++++++++++++++++++ v2/examples/systray/frontend/package.json | 13 + v2/examples/systray/go.mod | 35 + v2/examples/systray/go.sum | 82 ++ v2/examples/systray/iconDarkMode.png | Bin 0 -> 3167 bytes v2/examples/systray/iconLightMode.png | Bin 0 -> 3156 bytes v2/examples/systray/main.go | 177 ++++ v2/examples/systray/wails.json | 12 + 23 files changed, 1673 insertions(+) create mode 100644 v2/examples/README.md create mode 100644 v2/examples/common/fonts/OFL.txt create mode 100644 v2/examples/common/fonts/nunito-v16-latin-regular.woff2 create mode 100644 v2/examples/common/images/logo-universal.png create mode 100644 v2/examples/systray/.gitignore create mode 100644 v2/examples/systray/README.md create mode 100644 v2/examples/systray/build/appicon.png create mode 100644 v2/examples/systray/build/darwin/Info.plist create mode 100644 v2/examples/systray/build/windows/icon.ico create mode 100644 v2/examples/systray/build/windows/info.json create mode 100644 v2/examples/systray/build/windows/installer/project.nsi create mode 100644 v2/examples/systray/build/windows/installer/wails_tools.nsh create mode 100644 v2/examples/systray/build/windows/wails.exe.manifest create mode 100644 v2/examples/systray/frontend/dist/.gitkeep create mode 100644 v2/examples/systray/frontend/index.html create mode 100644 v2/examples/systray/frontend/package-lock.json create mode 100644 v2/examples/systray/frontend/package.json create mode 100644 v2/examples/systray/go.mod create mode 100644 v2/examples/systray/go.sum create mode 100644 v2/examples/systray/iconDarkMode.png create mode 100644 v2/examples/systray/iconLightMode.png create mode 100644 v2/examples/systray/main.go create mode 100644 v2/examples/systray/wails.json diff --git a/v2/examples/README.md b/v2/examples/README.md new file mode 100644 index 000000000..ec66688b8 --- /dev/null +++ b/v2/examples/README.md @@ -0,0 +1,15 @@ +

+ Wails logo
+

+ +

+Various example applications for Wails. +

+ +## Table of Contents + +- [Systray](./systray/README.md) + +## Contributing + +Please create a directory with your example, add a link to this README and raise a PR. diff --git a/v2/examples/common/fonts/OFL.txt b/v2/examples/common/fonts/OFL.txt new file mode 100644 index 000000000..9cac04ce8 --- /dev/null +++ b/v2/examples/common/fonts/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2016 The Nunito Project Authors (contact@sansoxygen.com), + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/v2/examples/common/fonts/nunito-v16-latin-regular.woff2 b/v2/examples/common/fonts/nunito-v16-latin-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..2f9cc5964455b8f5ca989db989250dbebb1a5f66 GIT binary patch literal 18972 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 DB$9&s literal 0 HcmV?d00001 diff --git a/v2/examples/systray/build/darwin/Info.plist b/v2/examples/systray/build/darwin/Info.plist new file mode 100644 index 000000000..303145e39 --- /dev/null +++ b/v2/examples/systray/build/darwin/Info.plist @@ -0,0 +1,14 @@ + + + CFBundlePackageTypeAPPL + CFBundleName{{.Info.ProductName}} + CFBundleExecutable{{.Name}} + CFBundleIdentifiercom.wails.{{.Name}} + CFBundleVersion{{.Info.ProductVersion}} + CFBundleGetInfoString{{.Info.Comments}} + CFBundleShortVersionString{{.Info.ProductVersion}} + CFBundleIconFileiconfile + LSMinimumSystemVersion10.13.0 + NSHighResolutionCapabletrue + NSHumanReadableCopyright{{.Info.Copyright}} + \ No newline at end of file diff --git a/v2/examples/systray/build/windows/icon.ico b/v2/examples/systray/build/windows/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f33479841c61728c8b5ee076ed13771c68e48b40 GIT binary patch literal 21017 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 wails build --target windows/amd64 --nsis +## Then you can call makensis on this file with specifying the path to your binary: +## For a AMD64 only installer: +## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app.exe +## For a ARM64 only installer: +## > makensis -DARG_WAILS_ARM64_BINARY=..\..\bin\app.exe +## For a installer with both architectures: +## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app-amd64.exe -DARG_WAILS_ARM64_BINARY=..\..\bin\app-arm64.exe +#### +## The following information is taken from the ProjectInfo file, but they can be overwritten here. +#### +## !define INFO_PROJECTNAME "MyProject" # Default "{{.Name}}" +## !define INFO_COMPANYNAME "MyCompany" # Default "{{.Info.CompanyName}}" +## !define INFO_PRODUCTNAME "MyProduct" # Default "{{.Info.ProductName}}" +## !define INFO_PRODUCTVERSION "1.0.0" # Default "{{.Info.ProductVersion}}" +## !define INFO_COPYRIGHT "Copyright" # Default "{{.Info.Copyright}}" +### +## !define PRODUCT_EXECUTABLE "Application.exe" # Default "${INFO_PROJECTNAME}.exe" +## !define UNINST_KEY_NAME "UninstKeyInRegistry" # Default "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}" +#### +## !define REQUEST_EXECUTION_LEVEL "admin" # Default "admin" see also https://nsis.sourceforge.io/Docs/Chapter4.html +#### +## Include the wails tools +#### +!include "wails_tools.nsh" + +# The version information for this two must consist of 4 parts +VIProductVersion "${INFO_PRODUCTVERSION}.0" +VIFileVersion "${INFO_PRODUCTVERSION}.0" + +VIAddVersionKey "CompanyName" "${INFO_COMPANYNAME}" +VIAddVersionKey "FileDescription" "${INFO_PRODUCTNAME} Installer" +VIAddVersionKey "ProductVersion" "${INFO_PRODUCTVERSION}" +VIAddVersionKey "FileVersion" "${INFO_PRODUCTVERSION}" +VIAddVersionKey "LegalCopyright" "${INFO_COPYRIGHT}" +VIAddVersionKey "ProductName" "${INFO_PRODUCTNAME}" + +!include "MUI.nsh" + +!define MUI_ICON "..\icon.ico" +!define MUI_UNICON "..\icon.ico" +# !define MUI_WELCOMEFINISHPAGE_BITMAP "resources\leftimage.bmp" #Include this to add a bitmap on the left side of the Welcome Page. Must be a size of 164x314 +!define MUI_FINISHPAGE_NOAUTOCLOSE # Wait on the INSTFILES page so the user can take a look into the details of the installation steps +!define MUI_ABORTWARNING # This will warn the user if they exit from the installer. + +!insertmacro MUI_PAGE_WELCOME # Welcome to the installer page. +# !insertmacro MUI_PAGE_LICENSE "resources\eula.txt" # Adds a EULA page to the installer +!insertmacro MUI_PAGE_DIRECTORY # In which folder install page. +!insertmacro MUI_PAGE_INSTFILES # Installing page. +!insertmacro MUI_PAGE_FINISH # Finished installation page. + +!insertmacro MUI_UNPAGE_INSTFILES # Uinstalling page + +!insertmacro MUI_LANGUAGE "English" # Set the Language of the installer + +## The following two statements can be used to sign the installer and the uninstaller. The path to the binaries are provided in %1 +#!uninstfinalize 'signtool --file "%1"' +#!finalize 'signtool --file "%1"' + +Name "${INFO_PRODUCTNAME}" +OutFile "..\..\bin\${INFO_PROJECTNAME}-${ARCH}-installer.exe" # Name of the installer's file. +InstallDir "$PROGRAMFILES64\${INFO_COMPANYNAME}\${INFO_PRODUCTNAME}" # Default installing folder ($PROGRAMFILES is Program Files folder). +ShowInstDetails show # This will always show the installation details. + +Function .onInit + !insertmacro wails.checkArchitecture +FunctionEnd + +Section + !insertmacro wails.webview2runtime + + SetOutPath $INSTDIR + + !insertmacro wails.files + + CreateShortcut "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" + CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" + + !insertmacro wails.writeUninstaller +SectionEnd + +Section "uninstall" + RMDir /r "$AppData\${PRODUCT_EXECUTABLE}" # Remove the WebView2 DataPath + + RMDir /r $INSTDIR + + Delete "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" + Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk" + + !insertmacro wails.deleteUninstaller +SectionEnd diff --git a/v2/examples/systray/build/windows/installer/wails_tools.nsh b/v2/examples/systray/build/windows/installer/wails_tools.nsh new file mode 100644 index 000000000..66dc209a3 --- /dev/null +++ b/v2/examples/systray/build/windows/installer/wails_tools.nsh @@ -0,0 +1,171 @@ +# DO NOT EDIT - Generated automatically by `wails build` + +!include "x64.nsh" +!include "WinVer.nsh" +!include "FileFunc.nsh" + +!ifndef INFO_PROJECTNAME + !define INFO_PROJECTNAME "{{.Name}}" +!endif +!ifndef INFO_COMPANYNAME + !define INFO_COMPANYNAME "{{.Info.CompanyName}}" +!endif +!ifndef INFO_PRODUCTNAME + !define INFO_PRODUCTNAME "{{.Info.ProductName}}" +!endif +!ifndef INFO_PRODUCTVERSION + !define INFO_PRODUCTVERSION "{{.Info.ProductVersion}}" +!endif +!ifndef INFO_COPYRIGHT + !define INFO_COPYRIGHT "{{.Info.Copyright}}" +!endif +!ifndef PRODUCT_EXECUTABLE + !define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe" +!endif +!ifndef UNINST_KEY_NAME + !define UNINST_KEY_NAME "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}" +!endif +!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINST_KEY_NAME}" + +!ifndef REQUEST_EXECUTION_LEVEL + !define REQUEST_EXECUTION_LEVEL "admin" +!endif + +RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}" + +!ifdef ARG_WAILS_AMD64_BINARY + !define SUPPORTS_AMD64 +!endif + +!ifdef ARG_WAILS_ARM64_BINARY + !define SUPPORTS_ARM64 +!endif + +!ifdef SUPPORTS_AMD64 + !ifdef SUPPORTS_ARM64 + !define ARCH "amd64_arm64" + !else + !define ARCH "amd64" + !endif +!else + !ifdef SUPPORTS_ARM64 + !define ARCH "arm64" + !else + !error "Wails: Undefined ARCH, please provide at least one of ARG_WAILS_AMD64_BINARY or ARG_WAILS_ARM64_BINARY" + !endif +!endif + +!macro wails.checkArchitecture + !ifndef WAILS_WIN10_REQUIRED + !define WAILS_WIN10_REQUIRED "This product is only supported on Windows 10 (Server 2016) and later." + !endif + + !ifndef WAILS_ARCHITECTURE_NOT_SUPPORTED + !define WAILS_ARCHITECTURE_NOT_SUPPORTED "This product can't be installed on the current Windows architecture. Supports: ${ARCH}" + !endif + + ${If} ${AtLeastWin10} + !ifdef SUPPORTS_AMD64 + ${if} ${IsNativeAMD64} + Goto ok + ${EndIf} + !endif + + !ifdef SUPPORTS_ARM64 + ${if} ${IsNativeARM64} + Goto ok + ${EndIf} + !endif + + IfSilent silentArch notSilentArch + silentArch: + SetErrorLevel 65 + Abort + notSilentArch: + MessageBox MB_OK "${WAILS_ARCHITECTURE_NOT_SUPPORTED}" + Quit + ${else} + IfSilent silentWin notSilentWin + silentWin: + SetErrorLevel 64 + Abort + notSilentWin: + MessageBox MB_OK "${WAILS_WIN10_REQUIRED}" + Quit + ${EndIf} + + ok: +!macroend + +!macro wails.files + !ifdef SUPPORTS_AMD64 + ${if} ${IsNativeAMD64} + File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_AMD64_BINARY}" + ${EndIf} + !endif + + !ifdef SUPPORTS_ARM64 + ${if} ${IsNativeARM64} + File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_ARM64_BINARY}" + ${EndIf} + !endif +!macroend + +!macro wails.writeUninstaller + WriteUninstaller "$INSTDIR\uninstall.exe" + + SetRegView 64 + WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}" + WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" + WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" + + ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 + IntFmt $0 "0x%08X" $0 + WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0" +!macroend + +!macro wails.deleteUninstaller + Delete "$INSTDIR\uninstall.exe" + + SetRegView 64 + DeleteRegKey HKLM "${UNINST_KEY}" +!macroend + +# Install webview2 by launching the bootstrapper +# See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment +!macro wails.webview2runtime + !ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT + !define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime" + !endif + + SetRegView 64 + # If the admin key exists and is not empty then webview2 is already installed + ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ${If} $0 != "" + Goto ok + ${EndIf} + + ${If} ${REQUEST_EXECUTION_LEVEL} == "user" + # If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed + ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ${If} $0 != "" + Goto ok + ${EndIf} + ${EndIf} + + SetDetailsPrint both + DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}" + SetDetailsPrint listonly + + InitPluginsDir + CreateDirectory "$pluginsdir\webview2bootstrapper" + SetOutPath "$pluginsdir\webview2bootstrapper" + File "tmp\MicrosoftEdgeWebview2Setup.exe" + ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install' + + SetDetailsPrint both + ok: +!macroend \ No newline at end of file diff --git a/v2/examples/systray/build/windows/wails.exe.manifest b/v2/examples/systray/build/windows/wails.exe.manifest new file mode 100644 index 000000000..17e1a2387 --- /dev/null +++ b/v2/examples/systray/build/windows/wails.exe.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + true/pm + permonitorv2,permonitor + + + \ No newline at end of file diff --git a/v2/examples/systray/frontend/dist/.gitkeep b/v2/examples/systray/frontend/dist/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/v2/examples/systray/frontend/index.html b/v2/examples/systray/frontend/index.html new file mode 100644 index 000000000..f11dd6326 --- /dev/null +++ b/v2/examples/systray/frontend/index.html @@ -0,0 +1,59 @@ + + + + + + Systray Example + + + +

+ + diff --git a/v2/examples/systray/frontend/package-lock.json b/v2/examples/systray/frontend/package-lock.json new file mode 100644 index 000000000..1f1e962f0 --- /dev/null +++ b/v2/examples/systray/frontend/package-lock.json @@ -0,0 +1,852 @@ +{ + "name": "frontend", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.0.0", + "devDependencies": { + "vite": "^2.9.9" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "2.77.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz", + "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/vite": { + "version": "2.9.15", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.15.tgz", + "integrity": "sha512-fzMt2jK4vQ3yK56te3Kqpkaeq9DkcZfBbzHwYpobasvgYmP2SoAr6Aic05CsB4CzCZbsDv4sujX3pkEGhLabVQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.14.27", + "postcss": "^8.4.13", + "resolve": "^1.22.0", + "rollup": ">=2.59.0 <2.78.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": ">=12.2.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "less": "*", + "sass": "*", + "stylus": "*" + }, + "peerDependenciesMeta": { + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + } + } + } + }, + "dependencies": { + "@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "dev": true, + "requires": { + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" + } + }, + "esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "dev": true, + "optional": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "postcss": { + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "2.77.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz", + "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "vite": { + "version": "2.9.15", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.15.tgz", + "integrity": "sha512-fzMt2jK4vQ3yK56te3Kqpkaeq9DkcZfBbzHwYpobasvgYmP2SoAr6Aic05CsB4CzCZbsDv4sujX3pkEGhLabVQ==", + "dev": true, + "requires": { + "esbuild": "^0.14.27", + "fsevents": "~2.3.2", + "postcss": "^8.4.13", + "resolve": "^1.22.0", + "rollup": ">=2.59.0 <2.78.0" + } + } + } +} diff --git a/v2/examples/systray/frontend/package.json b/v2/examples/systray/frontend/package.json new file mode 100644 index 000000000..4ac881798 --- /dev/null +++ b/v2/examples/systray/frontend/package.json @@ -0,0 +1,13 @@ +{ + "name": "frontend", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "vite": "^2.9.9" + } +} \ No newline at end of file diff --git a/v2/examples/systray/go.mod b/v2/examples/systray/go.mod new file mode 100644 index 000000000..83e7b2d26 --- /dev/null +++ b/v2/examples/systray/go.mod @@ -0,0 +1,35 @@ +module github.com/wailsapp/examples/systray + +go 1.18 + +require github.com/wailsapp/wails/v2 v2.0.0 + +require ( + github.com/bep/debounce v1.2.1 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect + github.com/labstack/echo/v4 v4.7.2 // indirect + github.com/labstack/gommon v0.3.1 // indirect + github.com/leaanthony/go-ansi-parser v1.0.1 // indirect + github.com/leaanthony/gosod v1.0.3 // indirect + github.com/leaanthony/slicer v1.5.0 // indirect + github.com/mattn/go-colorable v0.1.11 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/samber/lo v1.27.1 // indirect + github.com/tkrajina/go-reflector v0.5.5 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.1 // indirect + github.com/wailsapp/mimetype v1.4.1 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect + golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect + golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect + golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + golang.org/x/text v0.3.7 // indirect +) + +replace github.com/wailsapp/wails/v2 v2.0.0 => ../.. diff --git a/v2/examples/systray/go.sum b/v2/examples/systray/go.sum new file mode 100644 index 000000000..96ea787e0 --- /dev/null +++ b/v2/examples/systray/go.sum @@ -0,0 +1,82 @@ +github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= +github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= +github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= +github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI= +github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= +github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= +github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc= +github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA= +github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQOk2DgKxGG4= +github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM= +github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ= +github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4= +github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY= +github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc= +github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/samber/lo v1.27.1 h1:sTXwkRiIFIQG+G0HeAvOEnGjqWeWtI9cg5/n51KrxPg= +github.com/samber/lo v1.27.1/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= +github.com/tkrajina/go-reflector v0.5.5 h1:gwoQFNye30Kk7NrExj8zm3zFtrGPqOkzFMLuQZg1DtQ= +github.com/tkrajina/go-reflector v0.5.5/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= +github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= +golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6 h1:nfeHNc1nAqecKCy2FCy4HY+soOOe5sDLJ/gZLbx6GYI= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/v2/examples/systray/iconDarkMode.png b/v2/examples/systray/iconDarkMode.png new file mode 100644 index 0000000000000000000000000000000000000000..8d72ee490f6490f0ad01a685ee708cae021d1d50 GIT binary patch literal 3167 zcmai1dpy(o8~;vQZt1vGQpuXoh0RvP*k&$eWr!6{r!scM_ML4q%H@>X>7s;EluI4g zqC|d3lv`nuh*F}fl6#k<%ly8hQ>W88zuzCtMdjml|?E5 z0H{$M?cJbn8~LL&8~V)W2KE8~`~sKeDfXl~;eA0Kn$7@ym}m)40O0^&O_B)czWz)x z(uc|B@(HMs%4!sn%OIdU%&4YRfgO{>bqp0U-9w#ezM=lUmJAe$sA4U_LjpXen2wb2 z0{9}lgn*jX#Y4a4+ZYsbnj-cmpggIrNIOu-M4F+^(55J&3esB0VBy{D*MBjFRsmX?+nQyd0|Gl3W;q7c5AE-~SY^yLyW8um<)uaGMcb3r~* zu1WU+gTw?B3c`_J#Km0JH+8<~%kiN^VB`n}i#EmlmClrK|Aj6`exM6DpcoW!K*84o zeCOgT{DUEszJE56&;|cQrc(bmoyYs`7$UL5E+`RSlKNdte>xD+LIg~V8&d=Z34NIk zyO?~j{&XhfdBIb7bT-q8$!Ci>1eE#OzX2Xx#^3klLIFYYN^IeCA=kKXCZ69g0%{!& zgZ&11{Uan#HQtpgVFq~Gb9qd@2vYqT#W&FFUqCxB02I1IZOtU0W_*3E1AZE#f(!^+ zGabe^h+=2wDg;^F00Pxxk4N}VE{XNdB|$n!>UFY*N2CKLCNa-QbZK@$2QirN|Zgk;i<_bI$aqH6t|ZT5wj6WV_hi zrx3@F(#$SpX_wIME5$2XPpBR^o$uk7cP57avu%E!OKbefq>>`Vrq_}em;957?~6Je zva(f}o!4vg`DdezqH^xGS4bF>o775AyySM#h^@$~V(65)OW?-RExSsBE zC9c-toZ%d*=MLxCV=cLpAGBHk*^COJGpb97_-dZP{u?p@Hkui1nX)^4|cg;DZ>N*}C*v@Zt1 zsffOBki(t~bJio@J5p5f>*rYmM<<4#?euxVeyTPoPK4eT$^u6(5df%a$sZVSGHoFM zAZ}3X$uvpYQ0l`?i@g>$q$l2NwD7t#?A8-Uy_g#9c7d0Rpp2dI)4b^2p4w|{vb#Te z%Ax4}){U9Rqqi^EUPYmzCS)qogG!KAx7>!mT(#{Pj7ucbSK9p z!XiSp=LWwlLZ9N+8OoU-rH)ON@~ietj+c2FFHjuS18Q}Rf=7C*E>u>2JT4Y$baiz# z0&BOT77yY%dDzK%5(5SJoKmP0N8tu&Sr18lT%tce;xlp+mMT8 zHoR}~n+-RG3E4S039T>8!kQ3mP1?BI9GZdf4b~vC`DJ_QO6|VMi5C^bWF=S1AG25p z!An)7()DYDdx(cmoY1l3Jr!CS8yj=(|571VK91RGPAhVvifnKv>SBM=6Nhco_YMry z&?AL+loY)go@IzwQB}EiBciQYhWlM%Aeyucew&k&x5KQ(fV_jG+@uhf6(_O2MJv*P z74EE_o8H<;D_V3+6-hE|Zf>r)v|h(6^5Mhn=L!q`?)R39V)L9AJr_p8VA)kI^^~0$+*140I+CDVOq{CGhOyYCwbca$s_a{7^g<7{O?og}B{;dJ zp<(vjuCDp%yQ_BO>jBHf+10G#>Vv=6W;8!jXbkKa)mymG)x;>uTO`ujmY2lp*_S|m zcgyVp4LJRRthD*m=hBjrzNX~W`QcIO%Qcl97g@Dsx+)D9(Spn8&|f;as>9FT;ToHm ztR$*N+jf*&Ewc}P%VxdC)VskR@Yg*avrs`i3)V_-j0%l4pxEM0oW0xA(Gj(+jIZ-* zwb~tp?tnM*Q+kHBN@YtAD_-+Hg0DM&?wmIW9{zcxtxY}6xs%{ro1$6sQoQ%cKVH zTUn{SONxKFoqoQ&Mkc$O)$&Z3SyrYEYzNM(CHD8zy8}9VTFkd=H6Q&?lDBDGL&IZ_ zpr31(9P*1HxgJsy=zJXK2u7Qq*5?AUkgDc>WRX}{;r7ay1KK?)Ltc4an#-e* zOXljWT7$AFO-w&HxuoX8nmIstwO)92b(XnBeC_C{z~O3WhZ7Jo?ylkwe{dy4ODdJd ze5l_jJ({5dJEsznvEH)pLAgi?uCQOY046!@vAosKO$&Ct|H7;L=?;-HS-8ad^!^VG zwp6&QYQ)z3(lPSB%PB^O^+?0Iy1HSR9%S@!_w8fJkH;i5ZPR-J3+@G6M(xyR;7*v3 z)fE8Q%BhwPWsM9Al?(CkXQS32$B>K2ksX=01)v-yb{6X|&<~fn+syagv&Y(Cf7ZLr z@mjX#snkq~@D~^r;QINks=9P(!f2HRGwk3Iz?;V#@&NMhZ5{j+u`In6vnx0_HqAN5 zY{GSL*|u%ls!PhsrrY{7uBi-HIxm|<0eHO$1v(ukMrZhj3g@69=c7#A6 zL;!ziCpoe{*T?Bbs@BI@Dl0gyAWnqLi?DQ?9;L5xM@g)T`{$z$w#<_MFQ7O$+ZWn; G@BJ?xJR8UW literal 0 HcmV?d00001 diff --git a/v2/examples/systray/iconLightMode.png b/v2/examples/systray/iconLightMode.png new file mode 100644 index 0000000000000000000000000000000000000000..e8d3418756ac7e9f7f84586e557c1421c09fe789 GIT binary patch literal 3156 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 literal 0 HcmV?d00001 diff --git a/v2/examples/systray/main.go b/v2/examples/systray/main.go new file mode 100644 index 000000000..634518675 --- /dev/null +++ b/v2/examples/systray/main.go @@ -0,0 +1,177 @@ +package main + +import ( + "context" + "embed" + "fmt" + "github.com/wailsapp/wails/v2/pkg/application" + "github.com/wailsapp/wails/v2/pkg/menu" + "github.com/wailsapp/wails/v2/pkg/options" + "github.com/wailsapp/wails/v2/pkg/runtime" +) + +//go:embed all:frontend/dist +var assets embed.FS + +//go:embed iconLightMode.png +var lightModeIcon []byte + +//go:embed iconDarkMode.png +var darkModeIcon []byte + +func main() { + + var runtimeContext context.Context + + // Create a new Wails application using the current options + mainApp := application.NewWithOptions(&options.App{ + Assets: assets, + StartHidden: true, + HideWindowOnClose: true, + OnStartup: func(ctx context.Context) { + runtimeContext = ctx + }, + }) + + // ------------------------------------ + // Create a systray for the application + // Currently we only support PNG for icons + + systray := mainApp.NewSystemTray(&options.SystemTray{ + // This is the icon used when the system in using light mode + LightModeIcon: &options.SystemTrayIcon{ + Data: lightModeIcon, + }, + // This is the icon used when the system in using dark mode + DarkModeIcon: &options.SystemTrayIcon{ + Data: darkModeIcon, + }, + Tooltip: "Systray Example", + OnLeftClick: func() { + runtime.Show(runtimeContext) + }, + }) + + // ------------------------------------ + // Create some menus items that will be reused + + // This is a menuitem we will show/hide at runtime + visibleNotVisible := menu.Label("visible?").Show() + + var counter int + icons := [][]byte{lightModeIcon, darkModeIcon} + iconCounter := 0 + + disabledEnabledMenu := menu.Label("disabled").Disable().OnClick(func(c *menu.CallbackData) { + println("Disabled item clicked!") + }) + + // This checkbox menuitem will print the current checked state to the console when clicked. + // When a checkbox item is clicked, the state of the `Checked` variable is toggled. + // The UI automatically reflects the current state, even if this item is used multiple times. + mycheckbox := menu.Label("checked").SetChecked(true).OnClick(func(c *menu.CallbackData) { + println("My checked state is: ", c.MenuItem.Checked) + }) + + // This radio callback will be used by all the radio items. + // The CallbackData has a pointer back to the menuitem so we can determine + // which item was selected + radioCallback := func(data *menu.CallbackData) { + println("Radio item clicked:", data.MenuItem.Label) + } + + // We create 3 radio items , with the first being selected. They all share a callback. + radio1 := menu.Radio("Radio 1", true, nil, radioCallback) + radio2 := menu.Radio("Radio 2", false, nil, radioCallback) + radio3 := menu.Radio("Radio 3", false, nil, radioCallback) + + // Now we set the menu of the systray + systray.SetMenu(menu.NewMenuFromItems( + visibleNotVisible, + // This menu item changes its label when clicked. + menu.Label("Click Me!").OnClick(func(c *menu.CallbackData) { + c.MenuItem.SetLabel(fmt.Sprintf("Clicked %d times", counter)) + counter++ + systray.Update() + }), + + // We add a checkbox + menu.Separator(), + mycheckbox, + + // Next we create 2 radio groups containing the same menu items. + // It is perfectly fine to reuse radio item groups - the state and UI will + // stay in sync. Warning: Using the same radio item in different groups will + // lead to unspecified behaviour! + menu.Separator(), + radio1, + radio2, + radio3, + + menu.Separator(), + mycheckbox, + + menu.Label("Toggle items!").OnClick(func(c *menu.CallbackData) { + + iconCounter++ + + // Swap light and dark mode icons + systray.SetIcons(&options.SystemTrayIcon{ + Data: icons[iconCounter%2], + }, &options.SystemTrayIcon{ + Data: icons[(iconCounter+1)%2], + }) + + // Do some toggling + if iconCounter%2 == 0 { + visibleNotVisible.Show() + disabledEnabledMenu.Disable() + } else { + visibleNotVisible.Hide() + disabledEnabledMenu.Enable() + } + + // Update the menu + err := systray.Update() + if err != nil { + panic(err) + } + }), + + // We create a checkbox item that is initially unchecked. + menu.Label("unchecked").SetChecked(false).OnClick(func(c *menu.CallbackData) { + println("My checked state is: ", c.MenuItem.Checked) + systray.SetTooltip("My updated tooltip!") + }), + + // This menu item will toggle between enabled and disabled each time the "Toggle items!" menu + // option is selected + disabledEnabledMenu, + + // We now add a submenu, reusing the checkbox item and submenu we created earlier + menu.SubMenu("submenu", menu.NewMenuFromItems( + mycheckbox, + menu.Label("submenu item").OnClick(func(data *menu.CallbackData) { + println("submenu item clicked") + }), + menu.Separator(), + radio1, + radio2, + radio3, + )), + menu.Separator(), + menu.Label("quit").OnClick(func(_ *menu.CallbackData) { + println("Quitting application") + mainApp.Quit() + }), + )) + + println("Check out the system tray!") + + // Now we run the application + err := mainApp.Run() + + if err != nil { + println("Error:", err.Error()) + } +} diff --git a/v2/examples/systray/wails.json b/v2/examples/systray/wails.json new file mode 100644 index 000000000..f532e0088 --- /dev/null +++ b/v2/examples/systray/wails.json @@ -0,0 +1,12 @@ +{ + "name": "systray", + "outputfilename": "systray", + "frontend:install": "npm install", + "frontend:build": "npm run build", + "frontend:dev:watcher": "npm run dev", + "frontend:dev:serverUrl": "auto", + "author": { + "name": "Lea Anthony", + "email": "lea.anthony@gmail.com" + } +} From 7ef6f7d2b94bbf7d2e35c6233ea771900a660b99 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 11 Oct 2022 21:17:55 +1100 Subject: [PATCH 40/48] Fix bug in `runtime.Show()`. Tidy up debug. --- v2/examples/systray/frontend/dist/.gitkeep | 0 .../frontend/desktop/windows/frontend.go | 4 ++-- .../frontend/desktop/windows/win32/consts.go | 21 ++++++++++--------- .../frontend/desktop/windows/win32/window.go | 7 +++++++ v2/internal/platform/systray/windows.go | 1 - 5 files changed, 20 insertions(+), 13 deletions(-) delete mode 100644 v2/examples/systray/frontend/dist/.gitkeep diff --git a/v2/examples/systray/frontend/dist/.gitkeep b/v2/examples/systray/frontend/dist/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/v2/internal/frontend/desktop/windows/frontend.go b/v2/internal/frontend/desktop/windows/frontend.go index 59c3dcbdb..2d9d4c7ea 100644 --- a/v2/internal/frontend/desktop/windows/frontend.go +++ b/v2/internal/frontend/desktop/windows/frontend.go @@ -374,11 +374,11 @@ func (f *Frontend) ScreenGetAll() ([]Screen, error) { } func (f *Frontend) Show() { - f.mainWindow.Show() + f.WindowShow() } func (f *Frontend) Hide() { - f.mainWindow.Hide() + f.WindowHide() } func (f *Frontend) WindowIsMaximised() bool { diff --git a/v2/internal/frontend/desktop/windows/win32/consts.go b/v2/internal/frontend/desktop/windows/win32/consts.go index 6c6ba609c..e48bba3d9 100644 --- a/v2/internal/frontend/desktop/windows/win32/consts.go +++ b/v2/internal/frontend/desktop/windows/win32/consts.go @@ -13,20 +13,21 @@ type HANDLE uintptr type HMONITOR HANDLE var ( - moduser32 = syscall.NewLazyDLL("user32.dll") - procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") - procGetWindowLong = moduser32.NewProc("GetWindowLongW") - procSetClassLong = moduser32.NewProc("SetClassLongW") - procSetClassLongPtr = moduser32.NewProc("SetClassLongPtrW") - procShowWindow = moduser32.NewProc("ShowWindow") - procIsWindowVisible = moduser32.NewProc("IsWindowVisible") - procGetWindowRect = moduser32.NewProc("GetWindowRect") - procGetMonitorInfo = moduser32.NewProc("GetMonitorInfoW") - procMonitorFromWindow = moduser32.NewProc("MonitorFromWindow") + moduser32 = syscall.NewLazyDLL("user32.dll") + procSystemParametersInfo = moduser32.NewProc("SystemParametersInfoW") + procGetWindowLong = moduser32.NewProc("GetWindowLongW") + procSetClassLong = moduser32.NewProc("SetClassLongW") + procSetClassLongPtr = moduser32.NewProc("SetClassLongPtrW") + procShowWindow = moduser32.NewProc("ShowWindow") + procIsWindowVisible = moduser32.NewProc("IsWindowVisible") + procGetWindowRect = moduser32.NewProc("GetWindowRect") + procGetMonitorInfo = moduser32.NewProc("GetMonitorInfoW") + procMonitorFromWindow = moduser32.NewProc("MonitorFromWindow") procLookupIconIdFromDirectoryEx = moduser32.NewProc("LookupIconIdFromDirectoryEx") procCreateIconFromResourceEx = moduser32.NewProc("CreateIconFromResourceEx") procCreateIconIndirect = moduser32.NewProc("CreateIconIndirect") procLoadImageW = moduser32.NewProc("LoadImageW") + procBringWindowToTop = moduser32.NewProc("BringWindowToTop") ) var ( diff --git a/v2/internal/frontend/desktop/windows/win32/window.go b/v2/internal/frontend/desktop/windows/win32/window.go index 1d6c9438c..ff6df5ec3 100644 --- a/v2/internal/frontend/desktop/windows/win32/window.go +++ b/v2/internal/frontend/desktop/windows/win32/window.go @@ -218,3 +218,10 @@ func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool { ) return ret != 0 } + +func BringWindowToTop(hwnd uintptr) bool { + ret, _, _ := procBringWindowToTop.Call( + hwnd, + ) + return ret != 0 +} diff --git a/v2/internal/platform/systray/windows.go b/v2/internal/platform/systray/windows.go index 032067a13..3e2a1a873 100644 --- a/v2/internal/platform/systray/windows.go +++ b/v2/internal/platform/systray/windows.go @@ -314,7 +314,6 @@ func (p *Systray) Run() error { rt := win32.GetMessage(&msg) switch int(rt) { case 0: - println("Quitting Run()") return nil case -1: return errors.New("run failed") From 72a0db39385c313c4ecabdbb130490300cc3cd5d Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 11 Oct 2022 21:34:54 +1100 Subject: [PATCH 41/48] Add translucency effects --- v2/examples/systray/frontend/index.html | 2 +- v2/examples/systray/main.go | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/v2/examples/systray/frontend/index.html b/v2/examples/systray/frontend/index.html index f11dd6326..5451f1e30 100644 --- a/v2/examples/systray/frontend/index.html +++ b/v2/examples/systray/frontend/index.html @@ -6,7 +6,7 @@ Systray Example

``Cl35~rb|Fd`a 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�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 z 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