From 169abc2376d4187fb747df182c7b522976760b69 Mon Sep 17 00:00:00 2001 From: Gregor Biswanger Date: Wed, 13 May 2020 14:16:36 +0200 Subject: [PATCH] implement NativeTheme API with shouldUseDarkColors --- ElectronNET.API/Electron.cs | 5 ++ ElectronNET.API/NativeTheme.cs | 55 +++++++++++++++++++ .../Actions/DeployEmbeddedElectronFiles.cs | 1 + ElectronNET.CLI/ElectronNET.CLI.csproj | 1 + ElectronNET.Host/api/nativeTheme.js | 11 ++++ ElectronNET.Host/api/nativeTheme.js.map | 1 + ElectronNET.Host/api/nativeTheme.ts | 12 ++++ ElectronNET.Host/main.js | 4 +- 8 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 ElectronNET.API/NativeTheme.cs create mode 100644 ElectronNET.Host/api/nativeTheme.js create mode 100644 ElectronNET.Host/api/nativeTheme.js.map create mode 100644 ElectronNET.Host/api/nativeTheme.ts diff --git a/ElectronNET.API/Electron.cs b/ElectronNET.API/Electron.cs index cbee25f..730287d 100644 --- a/ElectronNET.API/Electron.cs +++ b/ElectronNET.API/Electron.cs @@ -78,5 +78,10 @@ /// Allows you to execute native Lock and Unlock process. /// public static PowerMonitor PowerMonitor { get { return PowerMonitor.Instance; } } + + /// + /// Read and respond to changes in Chromium's native color theme. + /// + public static NativeTheme NativeTheme { get { return NativeTheme.Instance; } } } } diff --git a/ElectronNET.API/NativeTheme.cs b/ElectronNET.API/NativeTheme.cs new file mode 100644 index 0000000..3b1721a --- /dev/null +++ b/ElectronNET.API/NativeTheme.cs @@ -0,0 +1,55 @@ +using System.Threading.Tasks; + +namespace ElectronNET.API +{ + /// + /// Read and respond to changes in Chromium's native color theme. + /// + public sealed class NativeTheme + { + private static NativeTheme _nativeTheme; + private static object _syncRoot = new object(); + + internal NativeTheme() { } + + internal static NativeTheme Instance + { + get + { + if (_nativeTheme == null) + { + lock (_syncRoot) + { + if (_nativeTheme == null) + { + _nativeTheme = new NativeTheme(); + } + } + } + + return _nativeTheme; + } + } + + /// + /// A `Boolean` for if the OS / Chromium currently has a dark mode enabled or is + /// being instructed to show a dark-style UI.If you want to modify this value you + /// should use `themeSource` below. + /// + /// + public Task ShouldUseDarkColorsAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("nativeTheme-shouldUseDarkColors-completed", (shouldUseDarkColors) => { + BridgeConnector.Socket.Off("nativeTheme-shouldUseDarkColors-completed"); + + taskCompletionSource.SetResult((bool)shouldUseDarkColors); + }); + + BridgeConnector.Socket.Emit("nativeTheme-shouldUseDarkColors"); + + return taskCompletionSource.Task; + } + } +} diff --git a/ElectronNET.CLI/Commands/Actions/DeployEmbeddedElectronFiles.cs b/ElectronNET.CLI/Commands/Actions/DeployEmbeddedElectronFiles.cs index a807b6a..a82775d 100644 --- a/ElectronNET.CLI/Commands/Actions/DeployEmbeddedElectronFiles.cs +++ b/ElectronNET.CLI/Commands/Actions/DeployEmbeddedElectronFiles.cs @@ -31,6 +31,7 @@ namespace ElectronNET.CLI.Commands.Actions EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "autoUpdater.js", "api."); EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "browserView.js", "api."); EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "powerMonitor.js", "api."); + EmbeddedFileHelper.DeployEmbeddedFile(hostApiFolder, "nativeTheme.js", "api."); string splashscreenFolder = Path.Combine(tempPath, "splashscreen"); if (Directory.Exists(splashscreenFolder) == false) diff --git a/ElectronNET.CLI/ElectronNET.CLI.csproj b/ElectronNET.CLI/ElectronNET.CLI.csproj index 2df604d..8caf82d 100644 --- a/ElectronNET.CLI/ElectronNET.CLI.csproj +++ b/ElectronNET.CLI/ElectronNET.CLI.csproj @@ -72,6 +72,7 @@ + diff --git a/ElectronNET.Host/api/nativeTheme.js b/ElectronNET.Host/api/nativeTheme.js new file mode 100644 index 0000000..e18bde2 --- /dev/null +++ b/ElectronNET.Host/api/nativeTheme.js @@ -0,0 +1,11 @@ +"use strict"; +const electron_1 = require("electron"); +let electronSocket; +module.exports = (socket) => { + electronSocket = socket; + socket.on('nativeTheme-shouldUseDarkColors', () => { + const shouldUseDarkColors = electron_1.nativeTheme.shouldUseDarkColors; + electronSocket.emit('nativeTheme-shouldUseDarkColors-completed', shouldUseDarkColors); + }); +}; +//# sourceMappingURL=nativeTheme.js.map \ No newline at end of file diff --git a/ElectronNET.Host/api/nativeTheme.js.map b/ElectronNET.Host/api/nativeTheme.js.map new file mode 100644 index 0000000..4da7e71 --- /dev/null +++ b/ElectronNET.Host/api/nativeTheme.js.map @@ -0,0 +1 @@ +{"version":3,"file":"nativeTheme.js","sourceRoot":"","sources":["nativeTheme.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,IAAI,cAAc,CAAC;AAEnB,iBAAS,CAAC,MAAuB,EAAE,EAAE;IACjC,cAAc,GAAG,MAAM,CAAC;IAExB,MAAM,CAAC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAC9C,MAAM,mBAAmB,GAAG,sBAAW,CAAC,mBAAmB,CAAC;QAE5D,cAAc,CAAC,IAAI,CAAC,2CAA2C,EAAE,mBAAmB,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;AACP,CAAC,CAAC"} \ No newline at end of file diff --git a/ElectronNET.Host/api/nativeTheme.ts b/ElectronNET.Host/api/nativeTheme.ts new file mode 100644 index 0000000..9781ffa --- /dev/null +++ b/ElectronNET.Host/api/nativeTheme.ts @@ -0,0 +1,12 @@ +import { nativeTheme } from 'electron'; +let electronSocket; + +export = (socket: SocketIO.Socket) => { + electronSocket = socket; + + socket.on('nativeTheme-shouldUseDarkColors', () => { + const shouldUseDarkColors = nativeTheme.shouldUseDarkColors; + + electronSocket.emit('nativeTheme-shouldUseDarkColors-completed', shouldUseDarkColors); + }); +}; diff --git a/ElectronNET.Host/main.js b/ElectronNET.Host/main.js index 15fe47f..60b4037 100644 --- a/ElectronNET.Host/main.js +++ b/ElectronNET.Host/main.js @@ -10,7 +10,7 @@ let globalShortcut, shellApi, screen, clipboard, autoUpdater; let commandLine, browserView; let powerMonitor; let splashScreen, hostHook; -let mainWindowId; +let mainWindowId, nativeTheme; let manifestJsonFileName = 'electron.manifest.json'; let watchable = false; @@ -154,6 +154,7 @@ function startSocketApiBridge(port) { delete require.cache[require.resolve('./api/clipboard')]; delete require.cache[require.resolve('./api/browserView')]; delete require.cache[require.resolve('./api/powerMonitor')]; + delete require.cache[require.resolve('./api/nativeTheme')]; }); global['electronsocket'] = socket; @@ -176,6 +177,7 @@ function startSocketApiBridge(port) { clipboard = require('./api/clipboard')(socket); browserView = require('./api/browserView')(socket); powerMonitor = require('./api/powerMonitor')(socket); + nativeTheme = require('./api/nativeTheme')(socket); try { const hostHookScriptFilePath = path.join(__dirname, 'ElectronHostHook', 'index.js');