🐛 Optimize the multi-platform experience of hide on close
This commit is contained in:
2
bin/cli.ts
vendored
2
bin/cli.ts
vendored
@@ -125,7 +125,7 @@ program
|
|||||||
.hideHelp(),
|
.hideHelp(),
|
||||||
)
|
)
|
||||||
.addOption(
|
.addOption(
|
||||||
new Option('--hide-on-close', 'Hide window on close instead of exiting')
|
new Option('--hide-on-close', 'Hide window on close instead of exiting (default: true for macOS, false for others)')
|
||||||
.default(DEFAULT.hideOnClose)
|
.default(DEFAULT.hideOnClose)
|
||||||
.hideHelp(),
|
.hideHelp(),
|
||||||
)
|
)
|
||||||
|
|||||||
2
bin/defaults.ts
vendored
2
bin/defaults.ts
vendored
@@ -22,7 +22,7 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = {
|
|||||||
debug: false,
|
debug: false,
|
||||||
inject: [],
|
inject: [],
|
||||||
installerLanguage: 'en-US',
|
installerLanguage: 'en-US',
|
||||||
hideOnClose: true,
|
hideOnClose: undefined, // Platform-specific: true for macOS, false for others
|
||||||
incognito: false,
|
incognito: false,
|
||||||
wasm: false,
|
wasm: false,
|
||||||
};
|
};
|
||||||
|
|||||||
5
bin/helpers/merge.ts
vendored
5
bin/helpers/merge.ts
vendored
@@ -65,6 +65,9 @@ export async function mergeConfig(
|
|||||||
|
|
||||||
const { platform } = process;
|
const { platform } = process;
|
||||||
|
|
||||||
|
// Platform-specific hide_on_close behavior: macOS keeps true, others default to false
|
||||||
|
const platformHideOnClose = hideOnClose ?? (platform === 'darwin');
|
||||||
|
|
||||||
// Set Windows parameters.
|
// Set Windows parameters.
|
||||||
const tauriConfWindowOptions = {
|
const tauriConfWindowOptions = {
|
||||||
width,
|
width,
|
||||||
@@ -76,7 +79,7 @@ export async function mergeConfig(
|
|||||||
always_on_top: alwaysOnTop,
|
always_on_top: alwaysOnTop,
|
||||||
dark_mode: darkMode,
|
dark_mode: darkMode,
|
||||||
disabled_web_shortcuts: disabledWebShortcuts,
|
disabled_web_shortcuts: disabledWebShortcuts,
|
||||||
hide_on_close: hideOnClose,
|
hide_on_close: platformHideOnClose,
|
||||||
incognito: incognito,
|
incognito: incognito,
|
||||||
title: title || null,
|
title: title || null,
|
||||||
enable_wasm: wasm,
|
enable_wasm: wasm,
|
||||||
|
|||||||
4
bin/types.ts
vendored
4
bin/types.ts
vendored
@@ -73,8 +73,8 @@ export interface PakeCliOptions {
|
|||||||
// Installer language, valid for Windows users, default is en-US
|
// Installer language, valid for Windows users, default is en-US
|
||||||
installerLanguage: string;
|
installerLanguage: string;
|
||||||
|
|
||||||
// Hide window on close instead of exiting, default false
|
// Hide window on close instead of exiting, platform-specific: true for macOS, false for others
|
||||||
hideOnClose: boolean;
|
hideOnClose: boolean | undefined;
|
||||||
|
|
||||||
// Launch app in incognito/private mode, default false
|
// Launch app in incognito/private mode, default false
|
||||||
incognito: boolean;
|
incognito: boolean;
|
||||||
|
|||||||
49
dist/cli.js
vendored
49
dist/cli.js
vendored
@@ -18,11 +18,10 @@ import axios from 'axios';
|
|||||||
import { dir } from 'tmp-promise';
|
import { dir } from 'tmp-promise';
|
||||||
import { fileTypeFromBuffer } from 'file-type';
|
import { fileTypeFromBuffer } from 'file-type';
|
||||||
import icongen from 'icon-gen';
|
import icongen from 'icon-gen';
|
||||||
import sharp from 'sharp';
|
|
||||||
import * as psl from 'psl';
|
import * as psl from 'psl';
|
||||||
|
|
||||||
var name = "pake-cli";
|
var name = "pake-cli";
|
||||||
var version = "3.2.17";
|
var version = "3.2.18";
|
||||||
var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。";
|
var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。";
|
||||||
var engines = {
|
var engines = {
|
||||||
node: ">=18.0.0"
|
node: ">=18.0.0"
|
||||||
@@ -72,7 +71,7 @@ var exports = "./dist/cli.js";
|
|||||||
var license = "MIT";
|
var license = "MIT";
|
||||||
var dependencies = {
|
var dependencies = {
|
||||||
"@tauri-apps/api": "^2.8.0",
|
"@tauri-apps/api": "^2.8.0",
|
||||||
"@tauri-apps/cli": "^2.8.1",
|
"@tauri-apps/cli": "^2.8.3",
|
||||||
axios: "^1.11.0",
|
axios: "^1.11.0",
|
||||||
chalk: "^5.6.0",
|
chalk: "^5.6.0",
|
||||||
commander: "^11.1.0",
|
commander: "^11.1.0",
|
||||||
@@ -84,7 +83,6 @@ var dependencies = {
|
|||||||
ora: "^8.2.0",
|
ora: "^8.2.0",
|
||||||
prompts: "^2.4.2",
|
prompts: "^2.4.2",
|
||||||
psl: "^1.15.0",
|
psl: "^1.15.0",
|
||||||
sharp: "^0.33.5",
|
|
||||||
"tmp-promise": "^3.0.3",
|
"tmp-promise": "^3.0.3",
|
||||||
"update-notifier": "^7.3.1"
|
"update-notifier": "^7.3.1"
|
||||||
};
|
};
|
||||||
@@ -103,11 +101,14 @@ var devDependencies = {
|
|||||||
"app-root-path": "^3.1.0",
|
"app-root-path": "^3.1.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
prettier: "^3.6.2",
|
prettier: "^3.6.2",
|
||||||
rollup: "^4.46.3",
|
rollup: "^4.49.0",
|
||||||
"rollup-plugin-typescript2": "^0.36.0",
|
"rollup-plugin-typescript2": "^0.36.0",
|
||||||
tslib: "^2.8.1",
|
tslib: "^2.8.1",
|
||||||
typescript: "^5.9.2"
|
typescript: "^5.9.2"
|
||||||
};
|
};
|
||||||
|
var optionalDependencies = {
|
||||||
|
sharp: "^0.33.5"
|
||||||
|
};
|
||||||
var packageJson = {
|
var packageJson = {
|
||||||
name: name,
|
name: name,
|
||||||
version: version,
|
version: version,
|
||||||
@@ -124,7 +125,8 @@ var packageJson = {
|
|||||||
exports: exports,
|
exports: exports,
|
||||||
license: license,
|
license: license,
|
||||||
dependencies: dependencies,
|
dependencies: dependencies,
|
||||||
devDependencies: devDependencies
|
devDependencies: devDependencies,
|
||||||
|
optionalDependencies: optionalDependencies
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convert the current module URL to a file path
|
// Convert the current module URL to a file path
|
||||||
@@ -349,6 +351,8 @@ async function mergeConfig(url, options, tauriConf) {
|
|||||||
}));
|
}));
|
||||||
const { width, height, fullscreen, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, incognito, title, wasm, } = options;
|
const { width, height, fullscreen, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, incognito, title, wasm, } = options;
|
||||||
const { platform } = process;
|
const { platform } = process;
|
||||||
|
// Platform-specific hide_on_close behavior: macOS keeps true, others default to false
|
||||||
|
const platformHideOnClose = hideOnClose ?? (platform === 'darwin');
|
||||||
// Set Windows parameters.
|
// Set Windows parameters.
|
||||||
const tauriConfWindowOptions = {
|
const tauriConfWindowOptions = {
|
||||||
width,
|
width,
|
||||||
@@ -360,7 +364,7 @@ async function mergeConfig(url, options, tauriConf) {
|
|||||||
always_on_top: alwaysOnTop,
|
always_on_top: alwaysOnTop,
|
||||||
dark_mode: darkMode,
|
dark_mode: darkMode,
|
||||||
disabled_web_shortcuts: disabledWebShortcuts,
|
disabled_web_shortcuts: disabledWebShortcuts,
|
||||||
hide_on_close: hideOnClose,
|
hide_on_close: platformHideOnClose,
|
||||||
incognito: incognito,
|
incognito: incognito,
|
||||||
title: title || null,
|
title: title || null,
|
||||||
enable_wasm: wasm,
|
enable_wasm: wasm,
|
||||||
@@ -1056,7 +1060,7 @@ const DEFAULT_PAKE_OPTIONS = {
|
|||||||
debug: false,
|
debug: false,
|
||||||
inject: [],
|
inject: [],
|
||||||
installerLanguage: 'en-US',
|
installerLanguage: 'en-US',
|
||||||
hideOnClose: true,
|
hideOnClose: undefined, // Platform-specific: true for macOS, false for others
|
||||||
incognito: false,
|
incognito: false,
|
||||||
wasm: false,
|
wasm: false,
|
||||||
};
|
};
|
||||||
@@ -1067,6 +1071,24 @@ async function checkUpdateTips() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lazy load sharp to handle installation issues gracefully
|
||||||
|
let sharp;
|
||||||
|
/**
|
||||||
|
* Safely loads sharp with fallback
|
||||||
|
*/
|
||||||
|
async function loadSharp() {
|
||||||
|
if (sharp)
|
||||||
|
return sharp;
|
||||||
|
try {
|
||||||
|
const sharpModule = await import('sharp');
|
||||||
|
sharp = sharpModule.default || sharpModule;
|
||||||
|
return sharp;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
logger.warn('Sharp not available, icon preprocessing will be skipped');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Constants
|
// Constants
|
||||||
const ICON_CONFIG = {
|
const ICON_CONFIG = {
|
||||||
minFileSize: 100,
|
minFileSize: 100,
|
||||||
@@ -1086,12 +1108,17 @@ const API_TOKENS = {
|
|||||||
*/
|
*/
|
||||||
async function preprocessIcon(inputPath) {
|
async function preprocessIcon(inputPath) {
|
||||||
try {
|
try {
|
||||||
const metadata = await sharp(inputPath).metadata();
|
const sharpInstance = await loadSharp();
|
||||||
|
if (!sharpInstance) {
|
||||||
|
logger.debug('Sharp not available, skipping icon preprocessing');
|
||||||
|
return inputPath;
|
||||||
|
}
|
||||||
|
const metadata = await sharpInstance(inputPath).metadata();
|
||||||
if (metadata.channels !== 4)
|
if (metadata.channels !== 4)
|
||||||
return inputPath; // No transparency
|
return inputPath; // No transparency
|
||||||
const { path: tempDir } = await dir();
|
const { path: tempDir } = await dir();
|
||||||
const outputPath = path.join(tempDir, 'icon-with-background.png');
|
const outputPath = path.join(tempDir, 'icon-with-background.png');
|
||||||
await sharp({
|
await sharpInstance({
|
||||||
create: {
|
create: {
|
||||||
width: metadata.width || 512,
|
width: metadata.width || 512,
|
||||||
height: metadata.height || 512,
|
height: metadata.height || 512,
|
||||||
@@ -1503,7 +1530,7 @@ program
|
|||||||
.addOption(new Option('--system-tray-icon <string>', 'Custom system tray icon')
|
.addOption(new Option('--system-tray-icon <string>', 'Custom system tray icon')
|
||||||
.default(DEFAULT_PAKE_OPTIONS.systemTrayIcon)
|
.default(DEFAULT_PAKE_OPTIONS.systemTrayIcon)
|
||||||
.hideHelp())
|
.hideHelp())
|
||||||
.addOption(new Option('--hide-on-close', 'Hide window on close instead of exiting')
|
.addOption(new Option('--hide-on-close', 'Hide window on close instead of exiting (default: true for macOS, false for others)')
|
||||||
.default(DEFAULT_PAKE_OPTIONS.hideOnClose)
|
.default(DEFAULT_PAKE_OPTIONS.hideOnClose)
|
||||||
.hideHelp())
|
.hideHelp())
|
||||||
.addOption(new Option('--title <string>', 'Window title').hideHelp())
|
.addOption(new Option('--title <string>', 'Window title').hideHelp())
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ Specify the system tray icon. This is only effective when the system tray is ena
|
|||||||
|
|
||||||
#### [hide-on-close]
|
#### [hide-on-close]
|
||||||
|
|
||||||
Hide window instead of closing the application when clicking close button. Default is `true`.
|
Hide window instead of closing the application when clicking close button. Platform-specific default: `true` for macOS, `false` for Windows/Linux.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
--hide-on-close
|
--hide-on-close
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ pake [url] [options]
|
|||||||
|
|
||||||
#### [hide-on-close]
|
#### [hide-on-close]
|
||||||
|
|
||||||
点击关闭按钮时隐藏窗口而不是退出应用程序。默认为 `true`。
|
点击关闭按钮时隐藏窗口而不是退出应用程序。平台特定默认值:macOS 为 `true`,Windows/Linux 为 `false`。
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
--hide-on-close
|
--hide-on-close
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
"activation_shortcut": "",
|
"activation_shortcut": "",
|
||||||
"disabled_web_shortcuts": false,
|
"disabled_web_shortcuts": false,
|
||||||
"hide_on_close": true,
|
"hide_on_close": true,
|
||||||
"incognito": false
|
"incognito": false,
|
||||||
|
"enable_wasm": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_agent": {
|
"user_agent": {
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ pub fn run_app() {
|
|||||||
.on_window_event(move |_window, _event| {
|
.on_window_event(move |_window, _event| {
|
||||||
if let tauri::WindowEvent::CloseRequested { api, .. } = _event {
|
if let tauri::WindowEvent::CloseRequested { api, .. } = _event {
|
||||||
if hide_on_close {
|
if hide_on_close {
|
||||||
|
// Hide window when hide_on_close is enabled (regardless of tray status)
|
||||||
let window = _window.clone();
|
let window = _window.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
@@ -77,8 +78,10 @@ pub fn run_app() {
|
|||||||
window.hide().unwrap();
|
window.hide().unwrap();
|
||||||
});
|
});
|
||||||
api.prevent_close();
|
api.prevent_close();
|
||||||
|
} else {
|
||||||
|
// Exit app completely when hide_on_close is false
|
||||||
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
// If hide_on_close is false, allow normal close behavior
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
|
|||||||
Reference in New Issue
Block a user