diff --git a/docs/src/content/docs/changelog.mdx b/docs/src/content/docs/changelog.mdx index 933331611..e3e3668bf 100644 --- a/docs/src/content/docs/changelog.mdx +++ b/docs/src/content/docs/changelog.mdx @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 */ ## [Unreleased] +- `app.Env.GetAccentColor` to get the accent color of a user's system. Works on MacOS. by [@etesam913](https://github.com/etesam913) ## v3.0.0-alpha.11 - 2025-07-12 @@ -34,7 +35,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## v3.0.0-alpha.10 - 2025-07-06 ### Breaking Changes - - **Manager API Refactoring**: Reorganized application API from flat structure to organized managers for better code organization and discoverability by [@leaanthony](https://github.com/leaanthony) in [#4359](https://github.com/wailsapp/wails/pull/4359) - `app.NewWebviewWindow()` → `app.Window.New()` - `app.CurrentWindow()` → `app.Window.Current()` diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 964de64eb..cb121df6a 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/wailsapp/wails/v3/internal/assetserver/bundledassets" "io" "log/slog" "net/http" @@ -17,6 +16,8 @@ import ( "strings" "sync" + "github.com/wailsapp/wails/v3/internal/assetserver/bundledassets" + "github.com/wailsapp/wails/v3/internal/signal" "github.com/wailsapp/wails/v3/internal/assetserver" @@ -197,6 +198,7 @@ type ( GetFlags(options Options) map[string]any isOnMainThread() bool isDarkMode() bool + getAccentColor() string } runnable interface { diff --git a/v3/pkg/application/application_darwin.go b/v3/pkg/application/application_darwin.go index ae4c20846..cb38f7e70 100644 --- a/v3/pkg/application/application_darwin.go +++ b/v3/pkg/application/application_darwin.go @@ -75,6 +75,32 @@ static bool isDarkMode(void) { return [interfaceStyle isEqualToString:@"Dark"]; } +static char* getAccentColor(void) { + @autoreleasepool { + NSColor *accentColor; + if (@available(macOS 10.14, *)) { + accentColor = [NSColor controlAccentColor]; + } else { + // Fallback to system blue for older macOS versions + accentColor = [NSColor systemBlueColor]; + } + // Convert to RGB color space + NSColor *rgbColor = [accentColor colorUsingColorSpace:[NSColorSpace sRGBColorSpace]]; + if (rgbColor == nil) { + rgbColor = accentColor; + } + // Get RGB components + CGFloat red, green, blue, alpha; + [rgbColor getRed:&red green:&green blue:&blue alpha:&alpha]; + // Convert to 0-255 range and format as rgb() string + int r = (int)(red * 255); + int g = (int)(green * 255); + int b = (int)(blue * 255); + NSString *colorString = [NSString stringWithFormat:@"rgb(%d,%d,%d)", r, g, b]; + return strdup([colorString UTF8String]); + } +} + static void setApplicationShouldTerminateAfterLastWindowClosed(bool shouldTerminate) { // Get the NSApp delegate AppDelegate *appDelegate = (AppDelegate*)[NSApp delegate]; @@ -188,6 +214,12 @@ func (m *macosApp) isDarkMode() bool { return bool(C.isDarkMode()) } +func (m *macosApp) getAccentColor() string { + accentColorC := C.getAccentColor() + defer C.free(unsafe.Pointer(accentColorC)) + return C.GoString(accentColorC) +} + func getNativeApplication() *macosApp { return globalApplication.impl.(*macosApp) } @@ -323,8 +355,8 @@ func processURLRequest(windowID C.uint, wkUrlSchemeTask unsafe.Pointer) { } webviewRequests <- &webViewAssetRequest{ - Request: webview.NewRequest(wkUrlSchemeTask), - windowId: uint(windowID), + Request: webview.NewRequest(wkUrlSchemeTask), + windowId: uint(windowID), windowName: window.Name(), } } diff --git a/v3/pkg/application/application_linux.go b/v3/pkg/application/application_linux.go index 2f8e5640a..b92c2c6aa 100644 --- a/v3/pkg/application/application_linux.go +++ b/v3/pkg/application/application_linux.go @@ -173,6 +173,12 @@ func (a *linuxApp) isDarkMode() bool { return strings.Contains(a.theme, "dark") } +func (a *linuxApp) getAccentColor() string { + // Linux doesn't have a unified system accent color API + // Return a default blue color + return "rgb(0,122,255)" +} + func (a *linuxApp) monitorThemeChanges() { go func() { defer handlePanic() diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 25c6363ba..7caf4f5c4 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -56,6 +56,12 @@ func (m *windowsApp) isDarkMode() bool { return w32.IsCurrentlyDarkMode() } +func (m *windowsApp) getAccentColor() string { + // Windows doesn't have a simple accent color API in the current w32 package + // Return a default blue color + return "rgb(0,122,255)" +} + func (m *windowsApp) isOnMainThread() bool { return m.mainThreadID == w32.GetCurrentThreadId() } diff --git a/v3/pkg/application/environment_manager.go b/v3/pkg/application/environment_manager.go index 55bd7284b..d32b6dd89 100644 --- a/v3/pkg/application/environment_manager.go +++ b/v3/pkg/application/environment_manager.go @@ -40,6 +40,14 @@ func (em *EnvironmentManager) IsDarkMode() bool { return em.app.impl.isDarkMode() } +// GetAccentColor returns the system accent color +func (em *EnvironmentManager) GetAccentColor() string { + if em.app.impl == nil { + return "rgb(0,122,255)" + } + return em.app.impl.getAccentColor() +} + // OpenFileManager opens the file manager at the specified path, optionally selecting the file func (em *EnvironmentManager) OpenFileManager(path string, selectFile bool) error { return InvokeSyncWithError(func() error {