diff --git a/v2/internal/ffenestri/ffenestri_darwin.c b/v2/internal/ffenestri/ffenestri_darwin.c index a6a95c15..afff648a 100644 --- a/v2/internal/ffenestri/ffenestri_darwin.c +++ b/v2/internal/ffenestri/ffenestri_darwin.c @@ -51,6 +51,9 @@ #define NSWindowBelow -1 #define NSWindowAbove 1 +#define NSSquareStatusItemLength -2.0 +#define NSVariableStatusItemLength -1.0 + #define NSWindowTitleHidden 1 #define NSWindowStyleMaskFullSizeContentView 1 << 15 @@ -381,9 +384,13 @@ void messageHandler(id self, SEL cmd, id contentController, id message) { if( strcmp(name, "completed") == 0) { // Delete handler msg(app->manager, s("removeScriptMessageHandlerForName:"), str("completed")); + + // TODO: Notify backend we're ready and get them to call back for the Show() if (app->startHidden == 0) { Show(app); } + + // TODO: Check this actually does reduce flicker msg(app->config, s("setValue:forKey:"), msg(c("NSNumber"), s("numberWithBool:"), 0), str("suppressesIncrementalRendering")); } else if( strcmp(name, "windowDrag") == 0 ) { // Guard against null events @@ -688,6 +695,15 @@ void ExecJS(struct Application *app, const char *js) { ); } +void emitThemeChange(struct Application *app) { + bool currentThemeIsDark = isDarkMode(app); + if (currentThemeIsDark) { + messageFromWindowCallback("ETT"); + } else { + messageFromWindowCallback("ETF"); + } +} + void themeChanged(id self, SEL cmd, id sender) { struct Application *app = (struct Application *)objc_getAssociatedObject( self, "application"); @@ -2268,8 +2284,6 @@ void processTrayIconData(struct Application *app) { break; } int length = atoi((const char *)lengthAsString); - printf("Got tray name: %s with data %p\n", name, data); - printf("Length = %d\n", length); // Create the icon and add to the hashmap id imageData = msg(c("NSData"), s("dataWithBytes:length:"), data, length); @@ -2295,7 +2309,7 @@ void parseTrayData(struct Application *app) { // Create a new menu bar if we need to if ( statusItem == NULL ) { id statusBar = msg( c("NSStatusBar"), s("systemStatusBar") ); - statusItem = msg(statusBar, s("statusItemWithLength:"), -1.0); + statusItem = msg(statusBar, s("statusItemWithLength:"), NSVariableStatusItemLength); app->statusItem = statusItem; msg(statusItem, s("retain")); id statusBarButton = msg(statusItem, s("button")); @@ -2550,7 +2564,10 @@ void Run(struct Application *app, int argc, char **argv) { 1)); + // Emit theme change event to notify of current system them +// emitThemeChange(app); + // If we want the webview to be transparent... if( app->webviewIsTranparent == 1 ) { msg(wkwebview, s("setValue:forKey:"), msg(c("NSNumber"), s("numberWithBool:"), 0), str("drawsBackground")); } diff --git a/v2/internal/runtime/events.go b/v2/internal/runtime/events.go index 5b721141..b3608593 100644 --- a/v2/internal/runtime/events.go +++ b/v2/internal/runtime/events.go @@ -11,6 +11,7 @@ type Events interface { Once(eventName string, callback func(optionalData ...interface{})) OnMultiple(eventName string, callback func(optionalData ...interface{}), maxCallbacks int) Emit(eventName string, optionalData ...interface{}) + OnThemeChange(callback func(darkMode bool)) } // event exposes the events interface @@ -66,3 +67,20 @@ func (r *event) Emit(eventName string, optionalData ...interface{}) { r.bus.Publish("event:emit:from:g", eventMessage) } + +// OnThemeChange allows you to register callbacks when the system theme changes +// from light or dark. +func (r *event) OnThemeChange(callback func(darkMode bool)) { + r.On("wails:system:themechange", func(data ...interface{}) { + if len(data) != 1 { + // TODO: Log error + return + } + darkMode, ok := data[0].(bool) + if !ok { + // TODO: Log error + return + } + callback(darkMode) + }) +} diff --git a/v2/internal/runtime/js/core/events.js b/v2/internal/runtime/js/core/events.js index fb190e57..79a5ad9a 100644 --- a/v2/internal/runtime/js/core/events.js +++ b/v2/internal/runtime/js/core/events.js @@ -71,6 +71,17 @@ export function On(eventName, callback) { OnMultiple(eventName, callback); } +/** + * Registers listeners for when the system theme changes from light/dark. A bool is + * sent to the listener, true if it is dark mode. + * + * @export + * @param {function} callback + */ +export function OnThemeChange(callback) { + On('wails:system:themechange', callback); +} + /** * Registers an event listener that will be invoked once then destroyed * @@ -118,7 +129,7 @@ function notifyListeners(eventData) { * Notify informs frontend listeners that an event was emitted with the given data * * @export - * @param {string} encoded notification message + * @param {string} notifyMessage - encoded notification message */ export function Notify(notifyMessage) { diff --git a/v2/internal/runtime/js/core/system.js b/v2/internal/runtime/js/core/system.js new file mode 100644 index 00000000..db79df66 --- /dev/null +++ b/v2/internal/runtime/js/core/system.js @@ -0,0 +1,26 @@ +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The lightweight framework for web-like apps +(c) Lea Anthony 2019-present +*/ +/* jshint esversion: 6 */ + +import * as Events from './events'; +import * as Store from './store'; + +// Set up stores +export const LogLevel = Store.New('wails:loglevel'); +export const AppConfig = Store.New('wails:appconfig'); + +// Set up dark mode +export let isDarkMode; + +// Register system event listener to keep isDarkMode up to date +Events.On('wails:system:themechange', (darkMode) => { + isDarkMode = darkMode; +}); + diff --git a/v2/internal/runtime/js/runtime/events.js b/v2/internal/runtime/js/runtime/events.js index cbf2f948..a065f87a 100644 --- a/v2/internal/runtime/js/runtime/events.js +++ b/v2/internal/runtime/js/runtime/events.js @@ -56,9 +56,20 @@ function Emit(eventName) { return window.wails.Events.Emit.apply(null, args); } +/** + * Registers listeners for when the system theme changes + * + * @export + * @param {function} callback + */ +function OnThemeChange(callback) { + On('wails:system:themechange', callback); +} + module.exports = { OnMultiple: OnMultiple, On: On, Once: Once, Emit: Emit, + OnThemeChange: OnThemeChange, }; \ No newline at end of file diff --git a/v2/internal/runtime/js/runtime/package.json b/v2/internal/runtime/js/runtime/package.json index cef50629..34a614cc 100644 --- a/v2/internal/runtime/js/runtime/package.json +++ b/v2/internal/runtime/js/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@wails/runtime", - "version": "1.2.12", + "version": "1.2.13", "description": "Wails V2 Javascript runtime library", "main": "main.js", "types": "runtime.d.ts", diff --git a/v2/test/kitchensink/.gitignore b/v2/test/kitchensink/.gitignore index 2f16e856..44f6bccd 100644 --- a/v2/test/kitchensink/.gitignore +++ b/v2/test/kitchensink/.gitignore @@ -1,2 +1 @@ -appicon.png info.plist \ No newline at end of file diff --git a/v2/test/kitchensink/appicon.png b/v2/test/kitchensink/appicon.png new file mode 100644 index 00000000..a3ad26ce Binary files /dev/null and b/v2/test/kitchensink/appicon.png differ diff --git a/v2/test/kitchensink/main.go b/v2/test/kitchensink/main.go index c720eb2f..83f90651 100644 --- a/v2/test/kitchensink/main.go +++ b/v2/test/kitchensink/main.go @@ -32,7 +32,7 @@ func main() { //Type: menu.TrayLabel, Type: menu.TrayIcon, Label: "Hi Go BitBar!", - Icon: "main", + Icon: "light", Menu: createApplicationTray(), }, }, diff --git a/v2/test/kitchensink/tray.go b/v2/test/kitchensink/tray.go index e75d66c7..8c387f03 100644 --- a/v2/test/kitchensink/tray.go +++ b/v2/test/kitchensink/tray.go @@ -44,6 +44,17 @@ func (t *Tray) WailsInit(runtime *wails.Runtime) error { t.runtime.Window.Unminimise() }) + t.runtime.Events.OnThemeChange(func(darkMode bool) { + if darkMode { + //t.runtime.Tray.SetIcon("light") + println("\n\n\n\n\n\nSET ICON TO LIGHT\n\n\n\n") + return + } + + //t.runtime.SetIcon("dark") + println("\n\n\n\n\n\nSET ICON TO DARK\n\n\n\n\n") + }) + // Start ticker //go t.startTicker() diff --git a/v2/test/kitchensink/trayicons/dark.png b/v2/test/kitchensink/trayicons/dark.png new file mode 100644 index 00000000..06d7136a Binary files /dev/null and b/v2/test/kitchensink/trayicons/dark.png differ diff --git a/v2/test/kitchensink/trayicons/light.png b/v2/test/kitchensink/trayicons/light.png new file mode 100644 index 00000000..482a54a3 Binary files /dev/null and b/v2/test/kitchensink/trayicons/light.png differ diff --git a/v2/test/kitchensink/trayicons/main.png b/v2/test/kitchensink/trayicons/main.png deleted file mode 100644 index a46bbdd8..00000000 Binary files a/v2/test/kitchensink/trayicons/main.png and /dev/null differ