add --maximize and --start-to-tray options

This commit is contained in:
Tw93
2025-10-17 18:00:28 +08:00
parent fcf807a88d
commit fabebdbd99
12 changed files with 109 additions and 11 deletions

View File

@@ -57,12 +57,14 @@ pnpm run dev # Development with hot reload
- **CLI Tool** (`bin/`): Main entry point, builders, options processing - **CLI Tool** (`bin/`): Main entry point, builders, options processing
- **Tauri App** (`src-tauri/`): Rust application, window/tray management, injection logic - **Tauri App** (`src-tauri/`): Rust application, window/tray management, injection logic
- **Config Files**: `pake.json`, `tauri.conf.json`, platform-specific configs - **Config Files**: `pake.json`, `tauri.conf.json`, platform-specific configs
- **Injection System** (`src-tauri/src/inject/event.js`): Custom event handlers, shortcuts, downloads, notifications
## Documentation Guidelines ## Documentation Guidelines
- **Main README**: Common parameters only - **Main README**: Common parameters only
- **CLI Documentation** (`docs/cli-usage.md`): ALL parameters with examples - **CLI Documentation** (`docs/cli-usage.md`): ALL parameters with examples
- **Rare parameters**: Full docs in CLI usage, minimal in main README - **Rare parameters**: Full docs in CLI usage, minimal in main README
- **NO technical documentation files**: Do not create separate technical docs, design docs, or implementation notes - keep technical details in memory/conversation only
## Platform Specifics ## Platform Specifics

10
bin/cli.ts vendored
View File

@@ -99,6 +99,11 @@ program
.default(DEFAULT.alwaysOnTop) .default(DEFAULT.alwaysOnTop)
.hideHelp(), .hideHelp(),
) )
.addOption(
new Option('--maximize', 'Start window maximized')
.default(DEFAULT.maximize)
.hideHelp(),
)
.addOption( .addOption(
new Option('--dark-mode', 'Force Mac app to use dark mode') new Option('--dark-mode', 'Force Mac app to use dark mode')
.default(DEFAULT.darkMode) .default(DEFAULT.darkMode)
@@ -164,6 +169,11 @@ program
.default(DEFAULT.multiInstance) .default(DEFAULT.multiInstance)
.hideHelp(), .hideHelp(),
) )
.addOption(
new Option('--start-to-tray', 'Start app minimized to tray')
.default(DEFAULT.startToTray)
.hideHelp(),
)
.addOption( .addOption(
new Option('--installer-language <string>', 'Installer language') new Option('--installer-language <string>', 'Installer language')
.default(DEFAULT.installerLanguage) .default(DEFAULT.installerLanguage)

2
bin/defaults.ts vendored
View File

@@ -5,6 +5,7 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = {
height: 780, height: 780,
width: 1200, width: 1200,
fullscreen: false, fullscreen: false,
maximize: false,
resizable: true, resizable: true,
hideTitleBar: false, hideTitleBar: false,
alwaysOnTop: false, alwaysOnTop: false,
@@ -28,6 +29,7 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = {
enableDragDrop: false, enableDragDrop: false,
keepBinary: false, keepBinary: false,
multiInstance: false, multiInstance: false,
startToTray: false,
}; };
// Just for cli development // Just for cli development

View File

@@ -49,6 +49,7 @@ export async function mergeConfig(
width, width,
height, height,
fullscreen, fullscreen,
maximize,
hideTitleBar, hideTitleBar,
alwaysOnTop, alwaysOnTop,
appVersion, appVersion,
@@ -71,6 +72,7 @@ export async function mergeConfig(
wasm, wasm,
enableDragDrop, enableDragDrop,
multiInstance, multiInstance,
startToTray,
} = options; } = options;
const { platform } = process; const { platform } = process;
@@ -81,6 +83,7 @@ export async function mergeConfig(
width, width,
height, height,
fullscreen, fullscreen,
maximize,
resizable, resizable,
hide_title_bar: hideTitleBar, hide_title_bar: hideTitleBar,
activation_shortcut: activationShortcut, activation_shortcut: activationShortcut,
@@ -92,6 +95,7 @@ export async function mergeConfig(
title: title || null, title: title || null,
enable_wasm: wasm, enable_wasm: wasm,
enable_drag_drop: enableDragDrop, enable_drag_drop: enableDragDrop,
start_to_tray: startToTray && showSystemTray,
}; };
Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions }); Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions });

6
bin/types.ts vendored
View File

@@ -24,6 +24,9 @@ export interface PakeCliOptions {
// Whether the window can be fullscreen, default false // Whether the window can be fullscreen, default false
fullscreen: boolean; fullscreen: boolean;
// Start window maximized, default false
maximize: boolean;
// Enable immersive header, default false. // Enable immersive header, default false.
hideTitleBar: boolean; hideTitleBar: boolean;
@@ -90,6 +93,9 @@ export interface PakeCliOptions {
// Allow multiple instances, default false (single instance) // Allow multiple instances, default false (single instance)
multiInstance: boolean; multiInstance: boolean;
// Start app minimized to tray, default false
startToTray: boolean;
} }
export interface PakeAppOptions extends PakeCliOptions { export interface PakeAppOptions extends PakeCliOptions {

View File

@@ -160,6 +160,15 @@ screen.
--fullscreen --fullscreen
``` ```
#### [maximize]
Determine whether the application launches with a maximized window. Default is `false`. Use the following command to enable
maximize.
```shell
--maximize
```
#### [activation-shortcut] #### [activation-shortcut]
Set the activation shortcut for the application. Default is empty, so it does not take effect. You can customize the activation shortcut with the following commands, e.g. `CmdOrControl+Shift+P`. Usage can refer to [available-modifiers](https://www.electronjs.org/docs/latest/api/accelerator#available-modifiers). Set the activation shortcut for the application. Default is empty, so it does not take effect. You can customize the activation shortcut with the following commands, e.g. `CmdOrControl+Shift+P`. Usage can refer to [available-modifiers](https://www.electronjs.org/docs/latest/api/accelerator#available-modifiers).
@@ -293,6 +302,19 @@ Hide window instead of closing the application when clicking close button. Platf
--hide-on-close false --hide-on-close false
``` ```
#### [start-to-tray]
Start the application minimized to system tray instead of showing the window. Must be used with `--show-system-tray`. Default is `false`.
```shell
--start-to-tray
# Example: Start hidden to tray (must use with --show-system-tray)
pake https://github.com --name GitHub --show-system-tray --start-to-tray
```
**Note**: Double-click the tray icon to show/hide the window. If used without `--show-system-tray`, this option is ignored.
#### [title] #### [title]
Set the window title bar text. macOS shows no title if not specified; Windows/Linux fallback to app name. Set the window title bar text. macOS shows no title if not specified; Windows/Linux fallback to app name.

View File

@@ -159,6 +159,14 @@ pake https://github.com --name GitHub
--fullscreen --fullscreen
``` ```
#### [maximize]
设置应用程序是否在启动时最大化窗口,默认为 `false`。使用以下命令可以设置应用程序启动时窗口最大化。
```shell
--maximize
```
#### [activation-shortcut] #### [activation-shortcut]
设置应用程序的激活快捷键。默认为空,不生效,可以使用以下命令自定义激活快捷键,例如 `CmdOrControl+Shift+P`,使用可参考 [available-modifiers](https://www.electronjs.org/docs/latest/api/accelerator#available-modifiers)。 设置应用程序的激活快捷键。默认为空,不生效,可以使用以下命令自定义激活快捷键,例如 `CmdOrControl+Shift+P`,使用可参考 [available-modifiers](https://www.electronjs.org/docs/latest/api/accelerator#available-modifiers)。
@@ -292,6 +300,19 @@ pake https://github.com --name GitHub
--hide-on-close false --hide-on-close false
``` ```
#### [start-to-tray]
启动时将应用程序最小化到系统托盘而不是显示窗口。必须与 `--show-system-tray` 一起使用。默认为 `false`。
```shell
--start-to-tray
# 示例:启动时隐藏到托盘(必须与 --show-system-tray 一起使用)
pake https://github.com --name GitHub --show-system-tray --start-to-tray
```
**注意**:双击托盘图标可以显示/隐藏窗口。如果不与 `--show-system-tray` 一起使用,此选项将被忽略。
#### [title] #### [title]
设置窗口标题栏文本macOS 未指定时不显示标题Windows/Linux 回退使用应用名称。 设置窗口标题栏文本macOS 未指定时不显示标题Windows/Linux 回退使用应用名称。

View File

@@ -1,6 +1,6 @@
{ {
"name": "pake-cli", "name": "pake-cli",
"version": "3.4.0", "version": "3.4.1",
"description": "🤱🏻 Turn any webpage into a desktop app with one command. 🤱🏻 一键打包网页生成轻量桌面应用。", "description": "🤱🏻 Turn any webpage into a desktop app with one command. 🤱🏻 一键打包网页生成轻量桌面应用。",
"engines": { "engines": {
"node": ">=18.0.0" "node": ">=18.0.0"

View File

@@ -15,7 +15,9 @@
"hide_on_close": true, "hide_on_close": true,
"incognito": false, "incognito": false,
"enable_wasm": false, "enable_wasm": false,
"enable_drag_drop": false "enable_drag_drop": false,
"maximize": false,
"start_to_tray": false
} }
], ],
"user_agent": { "user_agent": {

View File

@@ -5,6 +5,7 @@ pub struct WindowConfig {
pub url: String, pub url: String,
pub hide_title_bar: bool, pub hide_title_bar: bool,
pub fullscreen: bool, pub fullscreen: bool,
pub maximize: bool,
pub width: f64, pub width: f64,
pub height: f64, pub height: f64,
pub resizable: bool, pub resizable: bool,
@@ -18,6 +19,7 @@ pub struct WindowConfig {
pub title: Option<String>, pub title: Option<String>,
pub enable_wasm: bool, pub enable_wasm: bool,
pub enable_drag_drop: bool, pub enable_drag_drop: bool,
pub start_to_tray: bool,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]

View File

@@ -3,13 +3,13 @@ use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tauri::{ use tauri::{
menu::{MenuBuilder, MenuItemBuilder}, menu::{MenuBuilder, MenuItemBuilder},
tray::TrayIconBuilder, tray::{TrayIconBuilder, TrayIconEvent},
AppHandle, Manager, AppHandle, Manager,
}; };
use tauri_plugin_global_shortcut::{GlobalShortcutExt, Shortcut}; use tauri_plugin_global_shortcut::{GlobalShortcutExt, Shortcut};
use tauri_plugin_window_state::{AppHandleExt, StateFlags}; use tauri_plugin_window_state::{AppHandleExt, StateFlags};
pub fn set_system_tray(app: &AppHandle, show_system_tray: bool) -> tauri::Result<()> { pub fn set_system_tray(app: &AppHandle, show_system_tray: bool, tray_icon_path: &str) -> tauri::Result<()> {
if !show_system_tray { if !show_system_tray {
app.remove_tray_by_id("pake-tray"); app.remove_tray_by_id("pake-tray");
return Ok(()); return Ok(());
@@ -44,7 +44,30 @@ pub fn set_system_tray(app: &AppHandle, show_system_tray: bool) -> tauri::Result
} }
_ => (), _ => (),
}) })
.icon(app.default_window_icon().unwrap().clone()) .on_tray_icon_event(|tray, event| match event {
TrayIconEvent::Click { button, .. } => {
if button == tauri::tray::MouseButton::Left {
if let Some(window) = tray.app_handle().get_webview_window("pake") {
let is_visible = window.is_visible().unwrap_or(false);
if is_visible {
window.hide().unwrap();
} else {
window.show().unwrap();
window.set_focus().unwrap();
}
}
}
}
_ => {}
})
.icon(if tray_icon_path.is_empty() {
app.default_window_icon().unwrap_or_else(|| panic!("Failed to get default window icon")).clone()
} else {
tauri::image::Image::from_path(tray_icon_path).unwrap_or_else(|_| {
// If custom tray icon fails to load, fallback to default
app.default_window_icon().unwrap_or_else(|| panic!("Failed to get default window icon")).clone()
})
})
.build(app)?; .build(app)?;
tray.set_icon_as_template(false)?; tray.set_icon_as_template(false)?;

View File

@@ -24,6 +24,7 @@ pub fn run_app() {
let hide_on_close = pake_config.windows[0].hide_on_close; let hide_on_close = pake_config.windows[0].hide_on_close;
let activation_shortcut = pake_config.windows[0].activation_shortcut.clone(); let activation_shortcut = pake_config.windows[0].activation_shortcut.clone();
let init_fullscreen = pake_config.windows[0].fullscreen; let init_fullscreen = pake_config.windows[0].fullscreen;
let start_to_tray = pake_config.windows[0].start_to_tray && show_system_tray; // Only valid when tray is enabled
let multi_instance = pake_config.multi_instance; let multi_instance = pake_config.multi_instance;
let window_state_plugin = WindowStatePlugin::default() let window_state_plugin = WindowStatePlugin::default()
@@ -62,15 +63,18 @@ pub fn run_app() {
]) ])
.setup(move |app| { .setup(move |app| {
let window = set_window(app, &pake_config, &tauri_config); let window = set_window(app, &pake_config, &tauri_config);
set_system_tray(app.app_handle(), show_system_tray).unwrap(); set_system_tray(app.app_handle(), show_system_tray, &pake_config.system_tray_path).unwrap();
set_global_shortcut(app.app_handle(), activation_shortcut).unwrap(); set_global_shortcut(app.app_handle(), activation_shortcut).unwrap();
// Show window after state restoration to prevent position flashing // Show window after state restoration to prevent position flashing
// Unless start_to_tray is enabled, then keep it hidden
if !start_to_tray {
let window_clone = window.clone(); let window_clone = window.clone();
tauri::async_runtime::spawn(async move { tauri::async_runtime::spawn(async move {
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await; tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
window_clone.show().unwrap(); window_clone.show().unwrap();
}); });
}
Ok(()) Ok(())
}) })