5 窗口自定义

原文链接: https://tauri.app/learn/window-customization/

Tauri 提供了大量选项来自定义应用窗口的外观与感觉。你可以创建自定义标题栏、使用透明窗口、强制尺寸约束等等。

配置

有三种方式可以修改窗口配置:

用法

创建自定义标题栏

这些窗口特性的一种常见用法是创建自定义标题栏。下面这个简短的教程将带你完成该过程。

tauri.conf.json

在你的 tauri.conf.json 中把 decorations 设为 false:

1
2
3
4
5
6
7
"tauri": {
	"windows": [
		{
			"decorations": false
		}
	]
}

权限

在能力(capability)文件中添加窗口权限。

默认情况下,所有插件命令都被阻止、无法访问。你必须在 capabilities 配置中定义权限列表。

更多信息请参阅能力概述,以及使用插件权限的分步指南。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "main-capability",
  "description": "Capability for the main window",
  "windows": ["main"],
  "permissions": [
    "core:window:default",
    "core:window:allow-close",
    "core:window:allow-minimize",
    "core:window:allow-toggle-maximize",
    "core:window:allow-start-dragging"
  ]
}
权限说明
core:window:default该插件的默认权限。其中包含 core:window:allow-internal-toggle-maximize。
core:window:allow-close在没有预配置作用域的情况下启用 close 命令。
core:window:allow-minimize在没有预配置作用域的情况下启用 minimize 命令。
core:window:allow-start-dragging在没有预配置作用域的情况下启用 start_dragging 命令。
core:window:allow-toggle-maximize在没有预配置作用域的情况下启用 toggle_maximize 命令。
core:window:allow-internal-toggle-maximize在没有预配置作用域的情况下启用 internal_toggle_maximize 命令。

CSS

添加这段 CSS 示例,让它固定在屏幕顶部,并为按钮设置样式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.titlebar {
  height: 30px;
  background: #329ea3;
  user-select: none;
  display: grid;
  grid-template-columns: auto max-content;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}
.titlebar > .controls {
  display: flex;
}
.titlebar button {
  appearance: none;
  padding: 0;
  margin: 0;
  border: none;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  width: 30px;
  background-color: transparent;
}
.titlebar button:hover {
  background: #5bbec3;
}

HTML

把它放到 <body> 标签的顶部:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  <div data-tauri-drag-region></div>
  <div class="controls">
    <button id="titlebar-minimize" title="minimize">
      <!-- https://api.iconify.design/mdi:window-minimize.svg -->
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        viewBox="0 0 24 24"
      >
        <path fill="currentColor" d="M19 13H5v-2h14z" />
      </svg>
    </button>
    <button id="titlebar-maximize" title="maximize">
      <!-- https://api.iconify.design/mdi:window-maximize.svg -->
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        viewBox="0 0 24 24"
      >
        <path fill="currentColor" d="M4 4h16v16H4zm2 4v10h12V8z" />
      </svg>
    </button>
    <button id="titlebar-close" title="close">
      <!-- https://api.iconify.design/mdi:close.svg -->
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        viewBox="0 0 24 24"
      >
        <path
          fill="currentColor"
          d="M13.46 12L19 17.54V19h-1.46L12 13.46L6.46 19H5v-1.46L10.54 12L5 6.46V5h1.46L12 10.54L17.54 5H19v1.46z"
        />
      </svg>
    </button>
  </div>
</div>

注意你可能需要把其余内容向下移动,以免标题栏遮住它们。

JavaScript

使用这段代码让按钮生效:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { getCurrentWindow } from '@tauri-apps/api/window';

// 使用 `"withGlobalTauri": true` 时,你可以这样写
// const { getCurrentWindow } = window.__TAURI__.window;

const appWindow = getCurrentWindow();

document
  .getElementById('titlebar-minimize')
  ?.addEventListener('click', () => appWindow.minimize());
document
  .getElementById('titlebar-maximize')
  ?.addEventListener('click', () => appWindow.toggleMaximize());
document
  .getElementById('titlebar-close')
  ?.addEventListener('click', () => appWindow.close());

注意如果你使用基于 Rust 的前端,可以把上面的代码复制到 index.html 文件中的 <script> 元素里。

手动实现 data-tauri-drag-region

对于需要自定义拖动行为的场景,你可以改为手动用 window.startDragging 添加事件监听器,而不使用 data-tauri-drag-region。

HTML

基于上一节的代码,我们去掉 data-tauri-drag-region 并添加一个 id:

1
2
  <!-- ... -->
</div>

Javascript

为标题栏元素添加事件监听器:

1
2
3
4
5
6
7
8
document.getElementById('titlebar')?.addEventListener('mousedown', (e) => {
  if (e.buttons === 1) {
    // 主(左)键
    e.detail === 2
      ? appWindow.toggleMaximize() // 双击时最大化
      : appWindow.startDragging(); // 否则开始拖动
  }
});

(macOS)透明标题栏 + 自定义窗口背景色

我们将在 Rust 侧创建主窗口并修改它的背景色。

从 tauri.conf.json 文件中移除主窗口:

1
2
3
4
5
6
7
8
9
"tauri": {
	"windows": [
		{
			"title": "Transparent Titlebar Window",
			"width": 800,
			"height": 600
		}
	],
}

把 objc2-app-kit crate 加入依赖,这样我们就能用它调用 macOS 原生 API:

1
objc2-app-kit = { version = "0.3.2", features = ["NSColor", "NSWindow", "objc2-core-foundation"] }

创建主窗口并修改它的背景色:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use tauri::{TitleBarStyle, WebviewUrl, WebviewWindowBuilder};

pub fn run() {
	tauri::Builder::default()
		.setup(|app| {
			let win_builder =
				WebviewWindowBuilder::new(app, "main", WebviewUrl::default())
					.title("Transparent Titlebar Window")
					.inner_size(800.0, 600.0);

			// 仅在为 macOS 构建时设置透明标题栏
			#[cfg(target_os = "macos")]
			let win_builder = win_builder.title_bar_style(TitleBarStyle::Transparent);

			let window = win_builder.build().unwrap();

			// 仅在为 macOS 构建时设置背景色
			#[cfg(target_os = "macos")]
			{
				use objc2_app_kit::{NSColor, NSWindow};

				let ns_window_ptr = window.ns_window().unwrap() as *mut NSWindow;
				let ns_window = unsafe { &*ns_window_ptr };
				let bg_color = NSColor::colorWithRed_green_blue_alpha(
					50.0 / 255.0,
					158.0 / 255.0,
					163.5 / 255.0,
					1.0,
				);
				ns_window.setBackgroundColor(Some(&bg_color));
			}

			Ok(())
		})
		.run(tauri::generate_context!())
		.expect("error while running tauri application");
}
最后修改 September 25, 2026: 更新 (4c0ee2db0)