tauri-plugin-thumbar 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Miaoyww
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,185 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ # tauri-plugin-thumbar
2
+
3
+ Runtime-defined Windows taskbar thumbnail toolbar controls for Tauri applications.
4
+
5
+ The button list is supplied at runtime. Windows only lets an application add
6
+ buttons to a window's thumbnail toolbar once, so `initialize` takes the complete
7
+ list (up to 7 buttons) and `update` changes icon, tooltip, enabled and visible
8
+ state afterwards. `set_cover` replaces the taskbar hover thumbnail with a static
9
+ cover image.
10
+
11
+ ## Install
12
+
13
+ This plugin targets Tauri v2 and Rust 1.77.2+.
14
+
15
+ Add the Rust crate to your `src-tauri/Cargo.toml`:
16
+
17
+ ```toml
18
+ [dependencies]
19
+ tauri-plugin-thumbar = "0.1.0"
20
+ ```
21
+
22
+ Add the JS bindings package:
23
+
24
+ ```sh
25
+ pnpm add tauri-plugin-thumbar
26
+ ```
27
+
28
+ ## Rust setup
29
+
30
+ Register the plugin in your Tauri builder:
31
+
32
+ ```rust
33
+ fn run() {
34
+ tauri::Builder::default()
35
+ .plugin(tauri_plugin_thumbar::init())
36
+ .run(tauri::generate_context!())
37
+ .expect("error while running tauri app");
38
+ }
39
+ ```
40
+
41
+ Initialize the toolbar from the app setup hook:
42
+
43
+ ```rust
44
+ use tauri::Manager;
45
+ use tauri_plugin_thumbar::{Button, ThumbarExt};
46
+
47
+ tauri::Builder::default()
48
+ .plugin(tauri_plugin_thumbar::init())
49
+ .setup(|app| {
50
+ let window = app.get_webview_window("main").unwrap();
51
+
52
+ app.thumbar().initialize(
53
+ &window,
54
+ vec![
55
+ Button::new(1, "icons/thumbar/previous.ico")
56
+ .tooltip("Previous")
57
+ .event("thumbar-previous"),
58
+ Button::new(2, "icons/thumbar/play.ico")
59
+ .tooltip("Play")
60
+ .event("thumbar-toggle"),
61
+ Button::new(3, "icons/thumbar/next.ico")
62
+ .tooltip("Next")
63
+ .event("thumbar-next"),
64
+ ],
65
+ Some(Box::new(|window, id| {
66
+ // Runs on the window's UI thread. Do not block; forward to a
67
+ // channel or another thread instead.
68
+ let _ = (window, id);
69
+ })),
70
+ )?;
71
+
72
+ Ok(())
73
+ })
74
+ ```
75
+
76
+ Update a button later:
77
+
78
+ ```rust
79
+ use tauri_plugin_thumbar::ButtonUpdate;
80
+
81
+ app.thumbar().update(
82
+ &window,
83
+ ButtonUpdate::new(2)
84
+ .icon("icons/thumbar/pause.ico")
85
+ .tooltip("Pause"),
86
+ )?;
87
+
88
+ app.thumbar().update(&window, ButtonUpdate::new(3).enabled(false))?;
89
+ ```
90
+
91
+ ## Buttons
92
+
93
+ - At most **7** buttons are supported by the Windows thumbnail toolbar.
94
+ - `id` must be unique within the window and in `1..=65535`.
95
+ - `icon` is a Tauri resource path to an `.ico` file. Bundle the file through
96
+ `tauri.conf.json` (`bundle.resources`).
97
+ - `enabled` and `visible` default to `true`.
98
+ - `event` is optional. When set, the plugin emits that app event on click with
99
+ `{ id, window }` as the payload.
100
+
101
+ Buttons can only be added once per window. Use `update` to change the icon,
102
+ tooltip, enabled or visible state; use `visible: false` to hide a button instead
103
+ of removing it.
104
+
105
+ ## Cover
106
+
107
+ `set_cover` makes DWM render a static image in the taskbar hover thumbnail
108
+ instead of a live preview of the window. `clear_cover` restores the live
109
+ thumbnail.
110
+
111
+ The cover can come from an absolute local path or from encoded image bytes:
112
+
113
+ ```rust
114
+ use tauri_plugin_thumbar::{Cover, ThumbarExt};
115
+
116
+ app.thumbar().set_cover(&window, Some(Cover::from_path("/path/to/cover.jpg")))?;
117
+ app.thumbar().set_cover(&window, Some(Cover::from_bytes(cover_bytes)))?;
118
+ app.thumbar().set_cover(&window, None)?;
119
+ ```
120
+
121
+ From JavaScript:
122
+
123
+ ```ts
124
+ import { clearCover, setCoverFromBytes, setCoverFromPath } from 'tauri-plugin-thumbar'
125
+
126
+ await setCoverFromPath('C:\\cache\\cover.jpg')
127
+ await setCoverFromBytes(new Uint8Array(await response.arrayBuffer()))
128
+ await clearCover()
129
+ ```
130
+
131
+ - Call `initialize` before `set_cover`; the cover belongs to an initialized
132
+ window.
133
+ - PNG, JPEG, WebP and GIF are supported.
134
+ - The encoded image must not exceed **16 MiB**.
135
+ - Paths must be absolute; relative paths are rejected.
136
+ - The cover stays attached until `clear_cover` or the window is destroyed.
137
+ - The image is scaled to fit and letterboxed on black. It is rendered when DWM
138
+ requests the thumbnail, for both the iconic thumbnail and the peek preview.
139
+ - Setting `DWMWA_FORCE_ICONIC_REPRESENTATION` is required for this behavior.
140
+ It forces the iconic representation for the window's taskbar thumbnail and
141
+ peek preview; Windows versions that show a full-size peek preview from the
142
+ Alt+Tab switcher may therefore use the cover there as well.
143
+
144
+ ## JavaScript usage
145
+
146
+ Add the plugin's default permission to your capability (for example
147
+ `src-tauri/capabilities/default.json`):
148
+
149
+ ```json
150
+ {
151
+ "permissions": ["thumbar:default"]
152
+ }
153
+ ```
154
+
155
+ ```ts
156
+ import { initialize, isSupported, update } from 'tauri-plugin-thumbar'
157
+ import { listen } from '@tauri-apps/api/event'
158
+
159
+ if (await isSupported()) {
160
+ await initialize([
161
+ { id: 1, icon: 'icons/thumbar/previous.ico', tooltip: 'Previous', event: 'thumbar-previous' },
162
+ { id: 2, icon: 'icons/thumbar/play.ico', tooltip: 'Play', event: 'thumbar-toggle' },
163
+ { id: 3, icon: 'icons/thumbar/next.ico', tooltip: 'Next', event: 'thumbar-next' }
164
+ ])
165
+
166
+ await update({ id: 2, icon: 'icons/thumbar/pause.ico', tooltip: 'Pause' })
167
+
168
+ const unlisten = await listen<{ id: number; window: string }>('thumbar-toggle', (event) => {
169
+ console.log(event.payload.id, event.payload.window)
170
+ })
171
+ }
172
+ ```
173
+
174
+ ## Production notes
175
+
176
+ - This plugin does **not** set App User Model ID (AUMID). Set it once in your
177
+ app entrypoint if you need a stable shell identity for notifications, jump
178
+ lists or taskbar pinning.
179
+ - Ensure configured icon files are included as Tauri bundle resources.
180
+ - Non-Windows platforms intentionally succeed with no-op behavior for
181
+ cross-platform safety.
182
+ - The Rust click handler runs inside the window procedure on the UI thread.
183
+ Keep it non-blocking.
184
+ - If Explorer restarts, the plugin re-adds the current button state when the
185
+ taskbar button is recreated.
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ var core = require('@tauri-apps/api/core');
4
+
5
+ /**
6
+ * Adds the complete thumbnail toolbar button list to the current window.
7
+ *
8
+ * Windows only allows buttons to be added once per window. Call `update` for
9
+ * subsequent changes; at most 7 buttons are supported.
10
+ */
11
+ async function initialize(buttons) {
12
+ await core.invoke('plugin:thumbar|initialize', { buttons });
13
+ }
14
+ /**
15
+ * Updates an existing button's icon, tooltip, enabled or visible state.
16
+ */
17
+ async function update(button) {
18
+ await core.invoke('plugin:thumbar|update', { button });
19
+ }
20
+ /**
21
+ * Sets the taskbar hover thumbnail from an absolute local image path.
22
+ *
23
+ * PNG, JPEG, WebP and GIF are supported, up to 16 MiB.
24
+ */
25
+ async function setCoverFromPath(path) {
26
+ await core.invoke('plugin:thumbar|set_cover', { cover: { path } });
27
+ }
28
+ /**
29
+ * Sets the taskbar hover thumbnail from encoded image bytes.
30
+ *
31
+ * PNG, JPEG, WebP and GIF are supported, up to 16 MiB.
32
+ */
33
+ async function setCoverFromBytes(bytes) {
34
+ const data = toBase64(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes));
35
+ await core.invoke('plugin:thumbar|set_cover', { cover: { data } });
36
+ }
37
+ /**
38
+ * Restores the live window thumbnail on the taskbar.
39
+ */
40
+ async function clearCover() {
41
+ await core.invoke('plugin:thumbar|set_cover', { cover: null });
42
+ }
43
+ /**
44
+ * Returns whether the current platform supports native thumbnail toolbars.
45
+ */
46
+ async function isSupported() {
47
+ return await core.invoke('plugin:thumbar|is_supported');
48
+ }
49
+ function toBase64(bytes) {
50
+ let binary = '';
51
+ const chunkSize = 0x8000;
52
+ for (let index = 0; index < bytes.length; index += chunkSize) {
53
+ binary += String.fromCharCode(...bytes.subarray(index, index + chunkSize));
54
+ }
55
+ return btoa(binary);
56
+ }
57
+
58
+ exports.clearCover = clearCover;
59
+ exports.initialize = initialize;
60
+ exports.isSupported = isSupported;
61
+ exports.setCoverFromBytes = setCoverFromBytes;
62
+ exports.setCoverFromPath = setCoverFromPath;
63
+ exports.update = update;
@@ -0,0 +1,53 @@
1
+ export interface ThumbarButton {
2
+ /** Unique identifier within the window, in 1..=65535. */
3
+ id: number;
4
+ /** Tauri resource path to an .ico file. */
5
+ icon: string;
6
+ tooltip?: string;
7
+ enabled?: boolean;
8
+ visible?: boolean;
9
+ /** Optional app event emitted when the button is clicked. */
10
+ event?: string;
11
+ }
12
+ export interface ThumbarButtonUpdate {
13
+ id: number;
14
+ icon?: string;
15
+ tooltip?: string;
16
+ enabled?: boolean;
17
+ visible?: boolean;
18
+ }
19
+ export interface ThumbarClickEvent {
20
+ id: number;
21
+ window: string;
22
+ }
23
+ /**
24
+ * Adds the complete thumbnail toolbar button list to the current window.
25
+ *
26
+ * Windows only allows buttons to be added once per window. Call `update` for
27
+ * subsequent changes; at most 7 buttons are supported.
28
+ */
29
+ export declare function initialize(buttons: ThumbarButton[]): Promise<void>;
30
+ /**
31
+ * Updates an existing button's icon, tooltip, enabled or visible state.
32
+ */
33
+ export declare function update(button: ThumbarButtonUpdate): Promise<void>;
34
+ /**
35
+ * Sets the taskbar hover thumbnail from an absolute local image path.
36
+ *
37
+ * PNG, JPEG, WebP and GIF are supported, up to 16 MiB.
38
+ */
39
+ export declare function setCoverFromPath(path: string): Promise<void>;
40
+ /**
41
+ * Sets the taskbar hover thumbnail from encoded image bytes.
42
+ *
43
+ * PNG, JPEG, WebP and GIF are supported, up to 16 MiB.
44
+ */
45
+ export declare function setCoverFromBytes(bytes: Uint8Array | ArrayBuffer): Promise<void>;
46
+ /**
47
+ * Restores the live window thumbnail on the taskbar.
48
+ */
49
+ export declare function clearCover(): Promise<void>;
50
+ /**
51
+ * Returns whether the current platform supports native thumbnail toolbars.
52
+ */
53
+ export declare function isSupported(): Promise<boolean>;
@@ -0,0 +1,56 @@
1
+ import { invoke } from '@tauri-apps/api/core';
2
+
3
+ /**
4
+ * Adds the complete thumbnail toolbar button list to the current window.
5
+ *
6
+ * Windows only allows buttons to be added once per window. Call `update` for
7
+ * subsequent changes; at most 7 buttons are supported.
8
+ */
9
+ async function initialize(buttons) {
10
+ await invoke('plugin:thumbar|initialize', { buttons });
11
+ }
12
+ /**
13
+ * Updates an existing button's icon, tooltip, enabled or visible state.
14
+ */
15
+ async function update(button) {
16
+ await invoke('plugin:thumbar|update', { button });
17
+ }
18
+ /**
19
+ * Sets the taskbar hover thumbnail from an absolute local image path.
20
+ *
21
+ * PNG, JPEG, WebP and GIF are supported, up to 16 MiB.
22
+ */
23
+ async function setCoverFromPath(path) {
24
+ await invoke('plugin:thumbar|set_cover', { cover: { path } });
25
+ }
26
+ /**
27
+ * Sets the taskbar hover thumbnail from encoded image bytes.
28
+ *
29
+ * PNG, JPEG, WebP and GIF are supported, up to 16 MiB.
30
+ */
31
+ async function setCoverFromBytes(bytes) {
32
+ const data = toBase64(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes));
33
+ await invoke('plugin:thumbar|set_cover', { cover: { data } });
34
+ }
35
+ /**
36
+ * Restores the live window thumbnail on the taskbar.
37
+ */
38
+ async function clearCover() {
39
+ await invoke('plugin:thumbar|set_cover', { cover: null });
40
+ }
41
+ /**
42
+ * Returns whether the current platform supports native thumbnail toolbars.
43
+ */
44
+ async function isSupported() {
45
+ return await invoke('plugin:thumbar|is_supported');
46
+ }
47
+ function toBase64(bytes) {
48
+ let binary = '';
49
+ const chunkSize = 0x8000;
50
+ for (let index = 0; index < bytes.length; index += chunkSize) {
51
+ binary += String.fromCharCode(...bytes.subarray(index, index + chunkSize));
52
+ }
53
+ return btoa(binary);
54
+ }
55
+
56
+ export { clearCover, initialize, isSupported, setCoverFromBytes, setCoverFromPath, update };
package/package.json CHANGED
@@ -1,6 +1,37 @@
1
- {
2
- "name": "tauri-plugin-thumbar",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
1
+ {
2
+ "name": "tauri-plugin-thumbar",
3
+ "version": "0.1.0",
4
+ "description": "JavaScript bindings for tauri-plugin-thumbar",
5
+ "license": "MIT",
6
+ "authors": [
7
+ "Miaoyww"
8
+ ],
9
+ "repository": "https://github.com/Miaoyww/tauri-plugin-thumbar",
10
+ "type": "module",
11
+ "types": "./dist-js/index.d.ts",
12
+ "main": "./dist-js/index.cjs",
13
+ "module": "./dist-js/index.js",
14
+ "files": [
15
+ "dist-js",
16
+ "README.md"
17
+ ],
18
+ "exports": {
19
+ "types": "./dist-js/index.d.ts",
20
+ "import": "./dist-js/index.js",
21
+ "require": "./dist-js/index.cjs"
22
+ },
23
+ "scripts": {
24
+ "build": "rollup -c && tsc -p guest-js/tsconfig.json",
25
+ "typecheck": "tsc -p guest-js/tsconfig.json --noEmit"
26
+ },
27
+ "dependencies": {
28
+ "@tauri-apps/api": "^2.0.0"
29
+ },
30
+ "devDependencies": {
31
+ "@rollup/plugin-node-resolve": "^16.0.3",
32
+ "@rollup/plugin-typescript": "^12.3.0",
33
+ "rollup": "^4.60.2",
34
+ "tslib": "^2.8.1",
35
+ "typescript": "^5.6.0"
36
+ }
6
37
  }