From 7dd3f96915c4e6e281acdf76594e37cdd166de6c Mon Sep 17 00:00:00 2001 From: Sebastian Bauer Date: Thu, 31 Mar 2022 11:04:14 +0200 Subject: [PATCH] [Feature/1149] Dark mode: functions for manually switching theme (#1291) * [Feature/1149] Dark mode: functions for manually switching theme --- .../frontend/desktop/darwin/frontend.go | 12 +++++++++ .../frontend/desktop/linux/frontend.go | 12 +++++++++ .../frontend/desktop/windows/frontend.go | 27 +++++++++++++++++++ v2/internal/frontend/devserver/devserver.go | 12 +++++++++ v2/internal/frontend/dispatcher/window.go | 9 +++++++ v2/internal/frontend/frontend.go | 3 +++ .../frontend/runtime/desktop/window.js | 12 +++++++++ .../frontend/runtime/runtime_dev_desktop.js | 12 +++++++++ .../frontend/runtime/wrapper/runtime.d.ts | 6 +++++ .../frontend/runtime/wrapper/window.js | 12 +++++++++ v2/pkg/runtime/window.go | 15 +++++++++++ website/docs/reference/runtime/window.mdx | 27 +++++++++++++++++++ 12 files changed, 159 insertions(+) diff --git a/v2/internal/frontend/desktop/darwin/frontend.go b/v2/internal/frontend/desktop/darwin/frontend.go index 2ea6d8fda..09ce48a9c 100644 --- a/v2/internal/frontend/desktop/darwin/frontend.go +++ b/v2/internal/frontend/desktop/darwin/frontend.go @@ -125,6 +125,18 @@ func (f *Frontend) WindowReload() { f.ExecJS("runtime.WindowReload();") } +func (f *Frontend) WindowSetSystemDefaultTheme() { + return +} + +func (f *Frontend) WindowSetLightTheme() { + return +} + +func (f *Frontend) WindowSetDarkTheme() { + return +} + func (f *Frontend) Run(ctx context.Context) error { f.ctx = context.WithValue(ctx, "frontend", f) diff --git a/v2/internal/frontend/desktop/linux/frontend.go b/v2/internal/frontend/desktop/linux/frontend.go index 77451a3ec..3834376fa 100644 --- a/v2/internal/frontend/desktop/linux/frontend.go +++ b/v2/internal/frontend/desktop/linux/frontend.go @@ -114,6 +114,18 @@ func (f *Frontend) WindowReload() { f.ExecJS("runtime.WindowReload();") } +func (f *Frontend) WindowSetSystemDefaultTheme() { + return +} + +func (f *Frontend) WindowSetLightTheme() { + return +} + +func (f *Frontend) WindowSetDarkTheme() { + return +} + func (f *Frontend) Run(ctx context.Context) error { f.ctx = context.WithValue(ctx, "frontend", f) diff --git a/v2/internal/frontend/desktop/windows/frontend.go b/v2/internal/frontend/desktop/windows/frontend.go index 47ecbda00..16969629c 100644 --- a/v2/internal/frontend/desktop/windows/frontend.go +++ b/v2/internal/frontend/desktop/windows/frontend.go @@ -13,6 +13,8 @@ import ( "strings" "text/template" + "github.com/wailsapp/wails/v2/internal/system/operatingsystem" + "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/frontend/assetserver" @@ -23,6 +25,7 @@ import ( "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/system/operatingsystem" "github.com/wailsapp/wails/v2/pkg/options" + "github.com/wailsapp/wails/v2/pkg/options/windows" ) type Frontend struct { @@ -100,6 +103,30 @@ func (f *Frontend) WindowReload() { f.ExecJS("runtime.WindowReload();") } +func (f *Frontend) WindowSetSystemDefaultTheme() { + runtime.LockOSThread() + f.mainWindow.frontendOptions.Windows.Theme = windows.SystemDefault + f.mainWindow.Invoke(func() { + f.mainWindow.updateTheme() + }) +} + +func (f *Frontend) WindowSetLightTheme() { + runtime.LockOSThread() + f.mainWindow.frontendOptions.Windows.Theme = windows.Light + f.mainWindow.Invoke(func() { + f.mainWindow.updateTheme() + }) +} + +func (f *Frontend) WindowSetDarkTheme() { + runtime.LockOSThread() + f.mainWindow.frontendOptions.Windows.Theme = windows.Dark + f.mainWindow.Invoke(func() { + f.mainWindow.updateTheme() + }) +} + func (f *Frontend) Run(ctx context.Context) error { f.ctx = context.WithValue(ctx, "frontend", f) diff --git a/v2/internal/frontend/devserver/devserver.go b/v2/internal/frontend/devserver/devserver.go index 557a15e1e..5668fa668 100644 --- a/v2/internal/frontend/devserver/devserver.go +++ b/v2/internal/frontend/devserver/devserver.go @@ -47,6 +47,18 @@ type DevWebServer struct { devServerAddr string } +func (d *DevWebServer) WindowSetSystemDefaultTheme() { + d.desktopFrontend.WindowSetSystemDefaultTheme() +} + +func (d *DevWebServer) WindowSetLightTheme() { + d.desktopFrontend.WindowSetLightTheme() +} + +func (d *DevWebServer) WindowSetDarkTheme() { + d.desktopFrontend.WindowSetDarkTheme() +} + func (d *DevWebServer) Run(ctx context.Context) error { d.ctx = ctx diff --git a/v2/internal/frontend/dispatcher/window.go b/v2/internal/frontend/dispatcher/window.go index 11ca2e26f..de814fd5a 100644 --- a/v2/internal/frontend/dispatcher/window.go +++ b/v2/internal/frontend/dispatcher/window.go @@ -24,6 +24,15 @@ func (d *Dispatcher) processWindowMessage(message string, sender frontend.Fronte } switch message[1] { + case 'A': + switch message[2:] { + case "SDT": + go sender.WindowSetSystemDefaultTheme() + case "LT": + go sender.WindowSetLightTheme() + case "DT": + go sender.WindowSetDarkTheme() + } case 'c': go sender.WindowCenter() case 'T': diff --git a/v2/internal/frontend/frontend.go b/v2/internal/frontend/frontend.go index 398e984e1..0e4680589 100644 --- a/v2/internal/frontend/frontend.go +++ b/v2/internal/frontend/frontend.go @@ -87,6 +87,9 @@ type Frontend interface { WindowUnfullscreen() WindowSetRGBA(col *options.RGBA) WindowReload() + WindowSetSystemDefaultTheme() + WindowSetLightTheme() + WindowSetDarkTheme() // Menus MenuSetApplicationMenu(menu *menu.Menu) diff --git a/v2/internal/frontend/runtime/desktop/window.js b/v2/internal/frontend/runtime/desktop/window.js index e172cec50..1c66ac62c 100644 --- a/v2/internal/frontend/runtime/desktop/window.js +++ b/v2/internal/frontend/runtime/desktop/window.js @@ -17,6 +17,18 @@ export function WindowReload() { window.location.reload(); } +export function WindowSetSystemDefaultTheme() { + window.WailsInvoke('WASDT'); +} + +export function WindowSetLightTheme() { + window.WailsInvoke('WALT'); +} + +export function WindowSetDarkTheme() { + window.WailsInvoke('WADT'); +} + /** * Place the window in the center of the screen * diff --git a/v2/internal/frontend/runtime/runtime_dev_desktop.js b/v2/internal/frontend/runtime/runtime_dev_desktop.js index a6576c7eb..8b90d7b82 100644 --- a/v2/internal/frontend/runtime/runtime_dev_desktop.js +++ b/v2/internal/frontend/runtime/runtime_dev_desktop.js @@ -235,6 +235,9 @@ WindowMaximise: () => WindowMaximise, WindowMinimise: () => WindowMinimise, WindowReload: () => WindowReload, + WindowSetSystemDefaultTheme: () => WindowSetSystemDefaultTheme, + WindowSetLightTheme: () => WindowSetLightTheme, + WindowSetDarkTheme: () => WindowSetDarkTheme, WindowSetMaxSize: () => WindowSetMaxSize, WindowSetMinSize: () => WindowSetMinSize, WindowSetPosition: () => WindowSetPosition, @@ -250,6 +253,15 @@ function WindowReload() { window.location.reload(); } + function WindowSetSystemDefaultTheme() { + window.WailsInvoke('WASDT'); + } + function WindowSetLightTheme() { + window.WailsInvoke('WALT'); + } + function WindowSetDarkTheme() { + window.WailsInvoke('WADT'); + } function WindowCenter() { window.WailsInvoke("Wc"); } diff --git a/v2/internal/frontend/runtime/wrapper/runtime.d.ts b/v2/internal/frontend/runtime/wrapper/runtime.d.ts index 1145d3084..dea6eecf5 100644 --- a/v2/internal/frontend/runtime/wrapper/runtime.d.ts +++ b/v2/internal/frontend/runtime/wrapper/runtime.d.ts @@ -31,6 +31,12 @@ export interface runtime { WindowReload(): void; + WindowSetSystemDefaultTheme(): void; + + WindowSetLightTheme(): void; + + WindowSetDarkTheme(): void; + WindowCenter(): void; WindowSetTitle(title: string): void; diff --git a/v2/internal/frontend/runtime/wrapper/window.js b/v2/internal/frontend/runtime/wrapper/window.js index e54e33eba..3ed9a05ac 100644 --- a/v2/internal/frontend/runtime/wrapper/window.js +++ b/v2/internal/frontend/runtime/wrapper/window.js @@ -19,6 +19,18 @@ export function WindowReload() { window.runtime.WindowReload(); } +export function WindowSetSystemDefaultTheme() { + window.runtime.WindowSetSystemDefaultTheme(); +} + +export function WindowSetLightTheme() { + window.runtime.WindowSetLightTheme(); +} + +export function WindowSetDarkTheme() { + window.runtime.WindowSetDarkTheme(); +} + /** * Place the window in the center of the screen * diff --git a/v2/pkg/runtime/window.go b/v2/pkg/runtime/window.go index e76415356..9b6c1312c 100644 --- a/v2/pkg/runtime/window.go +++ b/v2/pkg/runtime/window.go @@ -36,6 +36,21 @@ func WindowReload(ctx context.Context) { appFrontend.WindowReload() } +func WindowSetSystemDefaultTheme(ctx context.Context) { + appFrontend := getFrontend(ctx) + appFrontend.WindowSetSystemDefaultTheme() +} + +func WindowSetLightTheme(ctx context.Context) { + appFrontend := getFrontend(ctx) + appFrontend.WindowSetLightTheme() +} + +func WindowSetDarkTheme(ctx context.Context) { + appFrontend := getFrontend(ctx) + appFrontend.WindowSetDarkTheme() +} + // WindowShow shows the window if hidden func WindowShow(ctx context.Context) { appFrontend := getFrontend(ctx) diff --git a/website/docs/reference/runtime/window.mdx b/website/docs/reference/runtime/window.mdx index cef929ad6..ee442b054 100644 --- a/website/docs/reference/runtime/window.mdx +++ b/website/docs/reference/runtime/window.mdx @@ -43,6 +43,33 @@ JS Signature: `WindowReload()` Performs a "reload" (Reloads index.html) +### WindowSetSystemDefaultTheme +Go Signature: `WindowSetSystemDefaultTheme(ctx context.Context)` + +JS Signature: `WindowSetSystemDefaultTheme()` + +Windows only. + +Sets window theme to system default (dark/light). + +### WindowSetLightTheme +Go Signature: `WindowSetLightTheme(ctx context.Context)` + +JS Signature: `WindowSetLightTheme()` + +Windows only. + +Sets window theme to light. + +### WindowSetDarkTheme +Go Signature: `WindowSetDarkTheme(ctx context.Context)` + +JS Signature: `WindowSetDarkTheme()` + +Windows only. + +Sets window theme to dark. + ### WindowShow Go Signature: `WindowShow(ctx context.Context)`