本教程将教你如何在你的应用程序中启用深色模式。将介绍如何让操作系统的原生界面(如文件选择器、窗口边框等)自动适应深色模式,以及如何让你的应用程序内部的界面也能根据用户的偏好自动或手动切换到深色模式。
自动更新应用的界面
如果你的应用程序有自己设计的界面,你也希望这些界面能够随着系统深色模式的变化而变化。这可以通过CSS媒体查询prefers-color-scheme
来实现。当系统切换到深色模式时,浏览器会自动应用针对深色模式定义的样式。
手动更新应用的界面
如果你想让用户能够手动选择亮色模式或深色模式,可以通过修改Electron的nativeTheme
模块的themeSource
属性来实现。这个改变会被传播到你的渲染进程中,任何与prefers-color-scheme
相关的CSS规则都会相应更新。
macOS 设置
- Mojave及更高版本:Apple从macOS Mojave开始引入了系统级别的深色模式。如果你的应用程序支持深色模式,你可以利用Electron的原生API来适配。
- Catalina及更高版本:Apple在macOS Catalina中增加了一个新的“自动”深色模式选项。为了确保API
isDarkMode
和Tray
在这种模式下正常工作,你需要在应用的Info.plist
文件中将NSRequiresAquaSystemAppearance
设置为false
,或者使用Electron 7.0.0或更高版本。使用Electron Packager或Electron Forge时,可以设置darwinDarkModeSupport
选项来自动处理这些更改。 - Electron 8.0.0及以上:从Electron 8.0.0开始,由于使用了macOS 10.14 SDK,你不能选择退出这种主题适配。
示例代码
接下来,我们来看一个简单的例子,展示如何在Electron应用程序中实现深色模式的切换。
index.html
这是应用程序的主页,定义了一些基本的HTML结构,包括两个按钮用于切换和重置主题,还有一个显示当前主题源的地方。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<link rel="stylesheet" type="text/css" href="./styles.css">
</head>
<body>
<h1>Hello World!</h1>
<p>当前主题来源: <strong id="theme-source">系统</strong></p>
<button id="toggle-dark-mode">切换深色模式</button>
<button id="reset-to-system">重置为系统主题</button>
<script src="renderer.js"></script>
</body>
</html>
styles.css
这里定义了两种不同的颜色方案,分别对应深色模式和浅色模式。
@media (prefers-color-scheme: dark) {
body { background: #333; color: white; }
}
@media (prefers-color-scheme: light) {
body { background: #ddd; color: black; }
}
preload.js
这部分代码创建了一个安全的API,让渲染进程可以请求主进程切换主题。
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('darkMode', {
toggle: () => ipcRenderer.invoke('dark-mode:toggle'),
system: () => ipcRenderer.invoke('dark-mode:system')
})
renderer.js
这里定义了按钮的行为,即当用户点击按钮时,应用程序如何响应。
document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
const isDarkMode = await window.darkMode.toggle()
document.getElementById('theme-source').innerHTML = isDarkMode ? '深色' : '浅色'
})
document.getElementById('reset-to-system').addEventListener('click', async () => {
await window.darkMode.system()
document.getElementById('theme-source').innerHTML = '系统'
})
main.js
这是应用程序的主进程,负责创建窗口并处理来自渲染进程的请求。
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
const path = require('path')
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
ipcMain.handle('dark-mode:toggle', () => {
nativeTheme.themeSource = nativeTheme.themeSource === 'dark' ? 'light' : 'dark'
return nativeTheme.shouldUseDarkColors
})
ipcMain.handle('dark-mode:system', () => {
nativeTheme.themeSource = 'system'
})
}
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
通过以上步骤,你就可以在你的Electron应用程序中实现深色模式的功能了,试试看吧!