pake-cli 3.4.0 โ 3.4.2
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/dist/cli.js +106 -18
- package/package.json +1 -1
- package/src-tauri/.pake/pake.json +2 -0
- package/src-tauri/pake.json +3 -1
- package/src-tauri/src/app/config.rs +2 -0
- package/src-tauri/src/app/setup.rs +34 -3
- package/src-tauri/src/app/window.rs +80 -14
- package/src-tauri/src/lib.rs +15 -6
package/dist/cli.js
CHANGED
|
@@ -23,7 +23,7 @@ import sharp from 'sharp';
|
|
|
23
23
|
import * as psl from 'psl';
|
|
24
24
|
|
|
25
25
|
var name = "pake-cli";
|
|
26
|
-
var version = "3.4.
|
|
26
|
+
var version = "3.4.2";
|
|
27
27
|
var description = "๐คฑ๐ป Turn any webpage into a desktop app with one command. ๐คฑ๐ป ไธ้ฎๆๅ
็ฝ้กต็ๆ่ฝป้ๆก้ขๅบ็จใ";
|
|
28
28
|
var engines = {
|
|
29
29
|
node: ">=18.0.0"
|
|
@@ -201,11 +201,13 @@ const IS_MAC = platform$1 === 'darwin';
|
|
|
201
201
|
const IS_WIN = platform$1 === 'win32';
|
|
202
202
|
const IS_LINUX = platform$1 === 'linux';
|
|
203
203
|
|
|
204
|
-
async function shellExec(command, timeout = 300000, env
|
|
204
|
+
async function shellExec(command, timeout = 300000, env) {
|
|
205
205
|
try {
|
|
206
206
|
const { exitCode } = await execa(command, {
|
|
207
207
|
cwd: npmDirectory,
|
|
208
|
-
|
|
208
|
+
// Use 'inherit' to show all output directly to user in real-time.
|
|
209
|
+
// This ensures linuxdeploy and other tool outputs are visible during builds.
|
|
210
|
+
stdio: 'inherit',
|
|
209
211
|
shell: true,
|
|
210
212
|
timeout,
|
|
211
213
|
env: env ? { ...process.env, ...env } : process.env,
|
|
@@ -219,15 +221,35 @@ async function shellExec(command, timeout = 300000, env, showOutput = false) {
|
|
|
219
221
|
throw new Error(`Command timed out after ${timeout}ms: "${command}". Try increasing timeout or check network connectivity.`);
|
|
220
222
|
}
|
|
221
223
|
let errorMsg = `Error occurred while executing command "${command}". Exit code: ${exitCode}. Details: ${errorMessage}`;
|
|
224
|
+
// Provide helpful guidance for common Linux AppImage build failures
|
|
225
|
+
// caused by strip tool incompatibility with modern glibc (2.38+)
|
|
226
|
+
const lowerError = errorMessage.toLowerCase();
|
|
222
227
|
if (process.platform === 'linux' &&
|
|
223
|
-
(
|
|
224
|
-
|
|
225
|
-
|
|
228
|
+
(lowerError.includes('linuxdeploy') ||
|
|
229
|
+
lowerError.includes('appimage') ||
|
|
230
|
+
lowerError.includes('strip'))) {
|
|
226
231
|
errorMsg +=
|
|
227
|
-
'\n\
|
|
228
|
-
'
|
|
229
|
-
'
|
|
230
|
-
'
|
|
232
|
+
'\n\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n' +
|
|
233
|
+
'Linux AppImage Build Failed\n' +
|
|
234
|
+
'โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n\n' +
|
|
235
|
+
'Cause: Strip tool incompatibility with glibc 2.38+\n' +
|
|
236
|
+
' (affects Debian Trixie, Arch Linux, and other modern distros)\n\n' +
|
|
237
|
+
'Quick fix:\n' +
|
|
238
|
+
' NO_STRIP=1 pake <url> --targets appimage --debug\n\n' +
|
|
239
|
+
'Alternatives:\n' +
|
|
240
|
+
' โข Use DEB format: pake <url> --targets deb\n' +
|
|
241
|
+
' โข Update binutils: sudo apt install binutils (or pacman -S binutils)\n' +
|
|
242
|
+
' โข Detailed guide: https://github.com/tw93/Pake/blob/main/docs/faq.md\n' +
|
|
243
|
+
'โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ';
|
|
244
|
+
if (lowerError.includes('fuse') ||
|
|
245
|
+
lowerError.includes('operation not permitted') ||
|
|
246
|
+
lowerError.includes('/dev/fuse')) {
|
|
247
|
+
errorMsg +=
|
|
248
|
+
'\n\nDocker / Container hint:\n' +
|
|
249
|
+
' AppImage tooling needs access to /dev/fuse. When running inside Docker, add:\n' +
|
|
250
|
+
' --privileged --device /dev/fuse --security-opt apparmor=unconfined\n' +
|
|
251
|
+
' or run on the host directly.';
|
|
252
|
+
}
|
|
231
253
|
}
|
|
232
254
|
throw new Error(errorMsg);
|
|
233
255
|
}
|
|
@@ -351,7 +373,7 @@ async function installRust() {
|
|
|
351
373
|
const rustInstallScriptForWindows = 'winget install --id Rustlang.Rustup';
|
|
352
374
|
const spinner = getSpinner('Downloading Rust...');
|
|
353
375
|
try {
|
|
354
|
-
await shellExec(IS_WIN ? rustInstallScriptForWindows : rustInstallScriptForMac, 300000, undefined
|
|
376
|
+
await shellExec(IS_WIN ? rustInstallScriptForWindows : rustInstallScriptForMac, 300000, undefined);
|
|
355
377
|
spinner.succeed(chalk.green('โ Rust installed successfully!'));
|
|
356
378
|
ensureRustEnv();
|
|
357
379
|
}
|
|
@@ -448,13 +470,14 @@ async function mergeConfig(url, options, tauriConf) {
|
|
|
448
470
|
await fsExtra.copy(sourcePath, destPath);
|
|
449
471
|
}
|
|
450
472
|
}));
|
|
451
|
-
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, enableDragDrop, multiInstance, } = options;
|
|
473
|
+
const { width, height, fullscreen, maximize, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, incognito, title, wasm, enableDragDrop, multiInstance, startToTray, } = options;
|
|
452
474
|
const { platform } = process;
|
|
453
475
|
const platformHideOnClose = hideOnClose ?? platform === 'darwin';
|
|
454
476
|
const tauriConfWindowOptions = {
|
|
455
477
|
width,
|
|
456
478
|
height,
|
|
457
479
|
fullscreen,
|
|
480
|
+
maximize,
|
|
458
481
|
resizable,
|
|
459
482
|
hide_title_bar: hideTitleBar,
|
|
460
483
|
activation_shortcut: activationShortcut,
|
|
@@ -466,6 +489,7 @@ async function mergeConfig(url, options, tauriConf) {
|
|
|
466
489
|
title: title || null,
|
|
467
490
|
enable_wasm: wasm,
|
|
468
491
|
enable_drag_drop: enableDragDrop,
|
|
492
|
+
start_to_tray: startToTray && showSystemTray,
|
|
469
493
|
};
|
|
470
494
|
Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions });
|
|
471
495
|
tauriConf.productName = name;
|
|
@@ -774,10 +798,10 @@ class BaseBuilder {
|
|
|
774
798
|
logger.info(`โบ Located in China, using ${packageManager}/rsProxy CN mirror.`);
|
|
775
799
|
const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml');
|
|
776
800
|
await fsExtra.copy(projectCnConf, projectConf);
|
|
777
|
-
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`, timeout, buildEnv
|
|
801
|
+
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`, timeout, buildEnv);
|
|
778
802
|
}
|
|
779
803
|
else {
|
|
780
|
-
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${peerDepsOption}`, timeout, buildEnv
|
|
804
|
+
await shellExec(`cd "${npmDirectory}" && ${packageManager} install${peerDepsOption}`, timeout, buildEnv);
|
|
781
805
|
}
|
|
782
806
|
spinner.succeed(chalk.green('Package installed!'));
|
|
783
807
|
if (!tauriTargetPathExists) {
|
|
@@ -802,11 +826,43 @@ class BaseBuilder {
|
|
|
802
826
|
buildSpinner.stop();
|
|
803
827
|
// Show static message to keep the status visible
|
|
804
828
|
logger.warn('โธ Building app...');
|
|
805
|
-
const
|
|
806
|
-
|
|
807
|
-
...(
|
|
829
|
+
const baseEnv = this.getBuildEnvironment();
|
|
830
|
+
let buildEnv = {
|
|
831
|
+
...(baseEnv ?? {}),
|
|
832
|
+
...(process.env.NO_STRIP ? { NO_STRIP: process.env.NO_STRIP } : {}),
|
|
808
833
|
};
|
|
809
|
-
|
|
834
|
+
const resolveExecEnv = () => Object.keys(buildEnv).length > 0 ? buildEnv : undefined;
|
|
835
|
+
// Warn users about potential AppImage build failures on modern Linux systems.
|
|
836
|
+
// The linuxdeploy tool bundled in Tauri uses an older strip tool that doesn't
|
|
837
|
+
// recognize the .relr.dyn section introduced in glibc 2.38+.
|
|
838
|
+
if (process.platform === 'linux' && this.options.targets === 'appimage') {
|
|
839
|
+
if (!buildEnv.NO_STRIP) {
|
|
840
|
+
logger.warn('โ Building AppImage on Linux may fail due to strip incompatibility with glibc 2.38+');
|
|
841
|
+
logger.warn('โ If build fails, retry with: NO_STRIP=1 pake <url> --targets appimage');
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
const buildCommand = `cd "${npmDirectory}" && ${this.getBuildCommand(packageManager)}`;
|
|
845
|
+
const buildTimeout = this.getBuildTimeout();
|
|
846
|
+
try {
|
|
847
|
+
await shellExec(buildCommand, buildTimeout, resolveExecEnv());
|
|
848
|
+
}
|
|
849
|
+
catch (error) {
|
|
850
|
+
const shouldRetryWithoutStrip = process.platform === 'linux' &&
|
|
851
|
+
this.options.targets === 'appimage' &&
|
|
852
|
+
!buildEnv.NO_STRIP &&
|
|
853
|
+
this.isLinuxDeployStripError(error);
|
|
854
|
+
if (shouldRetryWithoutStrip) {
|
|
855
|
+
logger.warn('โ AppImage build failed during linuxdeploy strip step, retrying with NO_STRIP=1 automatically.');
|
|
856
|
+
buildEnv = {
|
|
857
|
+
...buildEnv,
|
|
858
|
+
NO_STRIP: '1',
|
|
859
|
+
};
|
|
860
|
+
await shellExec(buildCommand, buildTimeout, resolveExecEnv());
|
|
861
|
+
}
|
|
862
|
+
else {
|
|
863
|
+
throw error;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
810
866
|
// Copy app
|
|
811
867
|
const fileName = this.getFileName();
|
|
812
868
|
const fileType = this.getFileType(target);
|
|
@@ -829,6 +885,18 @@ class BaseBuilder {
|
|
|
829
885
|
getFileType(target) {
|
|
830
886
|
return target;
|
|
831
887
|
}
|
|
888
|
+
isLinuxDeployStripError(error) {
|
|
889
|
+
if (!(error instanceof Error) || !error.message) {
|
|
890
|
+
return false;
|
|
891
|
+
}
|
|
892
|
+
const message = error.message.toLowerCase();
|
|
893
|
+
return (message.includes('linuxdeploy') ||
|
|
894
|
+
message.includes('failed to run linuxdeploy') ||
|
|
895
|
+
message.includes('strip:') ||
|
|
896
|
+
message.includes('unable to recognise the format of the input file') ||
|
|
897
|
+
message.includes('appimage tool failed') ||
|
|
898
|
+
message.includes('strip tool'));
|
|
899
|
+
}
|
|
832
900
|
/**
|
|
833
901
|
* ่งฃๆ็ฎๆ ๆถๆ
|
|
834
902
|
*/
|
|
@@ -865,6 +933,11 @@ class BaseBuilder {
|
|
|
865
933
|
if (target) {
|
|
866
934
|
fullCommand += ` --target ${target}`;
|
|
867
935
|
}
|
|
936
|
+
// Enable verbose output in debug mode to help diagnose build issues.
|
|
937
|
+
// This provides detailed logs from Tauri CLI and bundler tools.
|
|
938
|
+
if (this.options.debug) {
|
|
939
|
+
fullCommand += ' --verbose';
|
|
940
|
+
}
|
|
868
941
|
return fullCommand;
|
|
869
942
|
}
|
|
870
943
|
/**
|
|
@@ -1178,6 +1251,13 @@ class LinuxBuilder extends BaseBuilder {
|
|
|
1178
1251
|
if (features.length > 0) {
|
|
1179
1252
|
fullCommand += ` --features ${features.join(',')}`;
|
|
1180
1253
|
}
|
|
1254
|
+
// Enable verbose output for AppImage builds when debugging or PAKE_VERBOSE is set.
|
|
1255
|
+
// AppImage builds often fail with minimal error messages from linuxdeploy,
|
|
1256
|
+
// so verbose mode helps diagnose issues like strip failures and missing dependencies.
|
|
1257
|
+
if (this.options.targets === 'appimage' &&
|
|
1258
|
+
(this.options.debug || process.env.PAKE_VERBOSE)) {
|
|
1259
|
+
fullCommand += ' --verbose';
|
|
1260
|
+
}
|
|
1181
1261
|
return fullCommand;
|
|
1182
1262
|
}
|
|
1183
1263
|
getBasePath() {
|
|
@@ -1227,6 +1307,7 @@ const DEFAULT_PAKE_OPTIONS = {
|
|
|
1227
1307
|
height: 780,
|
|
1228
1308
|
width: 1200,
|
|
1229
1309
|
fullscreen: false,
|
|
1310
|
+
maximize: false,
|
|
1230
1311
|
hideTitleBar: false,
|
|
1231
1312
|
alwaysOnTop: false,
|
|
1232
1313
|
appVersion: '1.0.0',
|
|
@@ -1249,6 +1330,7 @@ const DEFAULT_PAKE_OPTIONS = {
|
|
|
1249
1330
|
enableDragDrop: false,
|
|
1250
1331
|
keepBinary: false,
|
|
1251
1332
|
multiInstance: false,
|
|
1333
|
+
startToTray: false,
|
|
1252
1334
|
};
|
|
1253
1335
|
|
|
1254
1336
|
async function checkUpdateTips() {
|
|
@@ -1731,6 +1813,9 @@ program
|
|
|
1731
1813
|
.addOption(new Option('--always-on-top', 'Always on the top level')
|
|
1732
1814
|
.default(DEFAULT_PAKE_OPTIONS.alwaysOnTop)
|
|
1733
1815
|
.hideHelp())
|
|
1816
|
+
.addOption(new Option('--maximize', 'Start window maximized')
|
|
1817
|
+
.default(DEFAULT_PAKE_OPTIONS.maximize)
|
|
1818
|
+
.hideHelp())
|
|
1734
1819
|
.addOption(new Option('--dark-mode', 'Force Mac app to use dark mode')
|
|
1735
1820
|
.default(DEFAULT_PAKE_OPTIONS.darkMode)
|
|
1736
1821
|
.hideHelp())
|
|
@@ -1774,6 +1859,9 @@ program
|
|
|
1774
1859
|
.addOption(new Option('--multi-instance', 'Allow multiple app instances')
|
|
1775
1860
|
.default(DEFAULT_PAKE_OPTIONS.multiInstance)
|
|
1776
1861
|
.hideHelp())
|
|
1862
|
+
.addOption(new Option('--start-to-tray', 'Start app minimized to tray')
|
|
1863
|
+
.default(DEFAULT_PAKE_OPTIONS.startToTray)
|
|
1864
|
+
.hideHelp())
|
|
1777
1865
|
.addOption(new Option('--installer-language <string>', 'Installer language')
|
|
1778
1866
|
.default(DEFAULT_PAKE_OPTIONS.installerLanguage)
|
|
1779
1867
|
.hideHelp())
|
package/package.json
CHANGED
package/src-tauri/pake.json
CHANGED
|
@@ -5,6 +5,7 @@ pub struct WindowConfig {
|
|
|
5
5
|
pub url: String,
|
|
6
6
|
pub hide_title_bar: bool,
|
|
7
7
|
pub fullscreen: bool,
|
|
8
|
+
pub maximize: bool,
|
|
8
9
|
pub width: f64,
|
|
9
10
|
pub height: f64,
|
|
10
11
|
pub resizable: bool,
|
|
@@ -18,6 +19,7 @@ pub struct WindowConfig {
|
|
|
18
19
|
pub title: Option<String>,
|
|
19
20
|
pub enable_wasm: bool,
|
|
20
21
|
pub enable_drag_drop: bool,
|
|
22
|
+
pub start_to_tray: bool,
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
#[derive(Debug, Serialize, Deserialize)]
|
|
@@ -3,13 +3,17 @@ use std::sync::{Arc, Mutex};
|
|
|
3
3
|
use std::time::{Duration, Instant};
|
|
4
4
|
use tauri::{
|
|
5
5
|
menu::{MenuBuilder, MenuItemBuilder},
|
|
6
|
-
tray::TrayIconBuilder,
|
|
6
|
+
tray::{TrayIconBuilder, TrayIconEvent},
|
|
7
7
|
AppHandle, Manager,
|
|
8
8
|
};
|
|
9
9
|
use tauri_plugin_global_shortcut::{GlobalShortcutExt, Shortcut};
|
|
10
10
|
use tauri_plugin_window_state::{AppHandleExt, StateFlags};
|
|
11
11
|
|
|
12
|
-
pub fn set_system_tray(
|
|
12
|
+
pub fn set_system_tray(
|
|
13
|
+
app: &AppHandle,
|
|
14
|
+
show_system_tray: bool,
|
|
15
|
+
tray_icon_path: &str,
|
|
16
|
+
) -> tauri::Result<()> {
|
|
13
17
|
if !show_system_tray {
|
|
14
18
|
app.remove_tray_by_id("pake-tray");
|
|
15
19
|
return Ok(());
|
|
@@ -44,7 +48,34 @@ pub fn set_system_tray(app: &AppHandle, show_system_tray: bool) -> tauri::Result
|
|
|
44
48
|
}
|
|
45
49
|
_ => (),
|
|
46
50
|
})
|
|
47
|
-
.
|
|
51
|
+
.on_tray_icon_event(|tray, event| match event {
|
|
52
|
+
TrayIconEvent::Click { button, .. } => {
|
|
53
|
+
if button == tauri::tray::MouseButton::Left {
|
|
54
|
+
if let Some(window) = tray.app_handle().get_webview_window("pake") {
|
|
55
|
+
let is_visible = window.is_visible().unwrap_or(false);
|
|
56
|
+
if is_visible {
|
|
57
|
+
window.hide().unwrap();
|
|
58
|
+
} else {
|
|
59
|
+
window.show().unwrap();
|
|
60
|
+
window.set_focus().unwrap();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
_ => {}
|
|
66
|
+
})
|
|
67
|
+
.icon(if tray_icon_path.is_empty() {
|
|
68
|
+
app.default_window_icon()
|
|
69
|
+
.unwrap_or_else(|| panic!("Failed to get default window icon"))
|
|
70
|
+
.clone()
|
|
71
|
+
} else {
|
|
72
|
+
tauri::image::Image::from_path(tray_icon_path).unwrap_or_else(|_| {
|
|
73
|
+
// If custom tray icon fails to load, fallback to default
|
|
74
|
+
app.default_window_icon()
|
|
75
|
+
.unwrap_or_else(|| panic!("Failed to get default window icon"))
|
|
76
|
+
.clone()
|
|
77
|
+
})
|
|
78
|
+
})
|
|
48
79
|
.build(app)?;
|
|
49
80
|
|
|
50
81
|
tray.set_icon_as_template(false)?;
|
|
@@ -6,6 +6,22 @@ use tauri::{App, Config, Url, WebviewUrl, WebviewWindow, WebviewWindowBuilder};
|
|
|
6
6
|
#[cfg(target_os = "macos")]
|
|
7
7
|
use tauri::{Theme, TitleBarStyle};
|
|
8
8
|
|
|
9
|
+
#[cfg(target_os = "windows")]
|
|
10
|
+
fn build_proxy_browser_arg(url: &Url) -> Option<String> {
|
|
11
|
+
let host = url.host_str()?;
|
|
12
|
+
let scheme = url.scheme();
|
|
13
|
+
let port = url.port().or_else(|| match scheme {
|
|
14
|
+
"http" => Some(80),
|
|
15
|
+
"socks5" => Some(1080),
|
|
16
|
+
_ => None,
|
|
17
|
+
})?;
|
|
18
|
+
|
|
19
|
+
match scheme {
|
|
20
|
+
"http" | "socks5" => Some(format!("--proxy-server={scheme}://{host}:{port}")),
|
|
21
|
+
_ => None,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
9
25
|
pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) -> WebviewWindow {
|
|
10
26
|
let package_name = tauri_config.clone().product_name.unwrap();
|
|
11
27
|
let _data_dir = get_data_dir(app.handle(), package_name);
|
|
@@ -43,6 +59,7 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
|
|
|
43
59
|
.user_agent(user_agent)
|
|
44
60
|
.resizable(window_config.resizable)
|
|
45
61
|
.fullscreen(window_config.fullscreen)
|
|
62
|
+
.maximized(window_config.maximize)
|
|
46
63
|
.inner_size(window_config.width, window_config.height)
|
|
47
64
|
.always_on_top(window_config.always_on_top)
|
|
48
65
|
.incognito(window_config.incognito);
|
|
@@ -59,20 +76,36 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
|
|
|
59
76
|
.initialization_script(include_str!("../inject/style.js"))
|
|
60
77
|
.initialization_script(include_str!("../inject/custom.js"));
|
|
61
78
|
|
|
79
|
+
#[cfg(target_os = "windows")]
|
|
80
|
+
let mut windows_browser_args = String::from("--disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection --disable-blink-features=AutomationControlled");
|
|
81
|
+
|
|
82
|
+
#[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
|
|
83
|
+
let mut linux_browser_args = String::from("--disable-blink-features=AutomationControlled");
|
|
84
|
+
|
|
62
85
|
if window_config.enable_wasm {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
.
|
|
66
|
-
|
|
86
|
+
#[cfg(target_os = "windows")]
|
|
87
|
+
{
|
|
88
|
+
windows_browser_args.push_str(" --enable-features=SharedArrayBuffer");
|
|
89
|
+
windows_browser_args.push_str(" --enable-unsafe-webgpu");
|
|
90
|
+
}
|
|
67
91
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
92
|
+
#[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
|
|
93
|
+
{
|
|
94
|
+
linux_browser_args.push_str(" --enable-features=SharedArrayBuffer");
|
|
95
|
+
linux_browser_args.push_str(" --enable-unsafe-webgpu");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#[cfg(target_os = "macos")]
|
|
99
|
+
{
|
|
100
|
+
window_builder = window_builder
|
|
101
|
+
.additional_browser_args("--enable-features=SharedArrayBuffer")
|
|
102
|
+
.additional_browser_args("--enable-unsafe-webgpu");
|
|
73
103
|
}
|
|
74
104
|
}
|
|
75
105
|
|
|
106
|
+
let mut parsed_proxy_url: Option<Url> = None;
|
|
107
|
+
|
|
108
|
+
// Platform-specific configuration must be set before proxy on Windows/Linux
|
|
76
109
|
#[cfg(target_os = "macos")]
|
|
77
110
|
{
|
|
78
111
|
let title_bar_style = if window_config.hide_title_bar {
|
|
@@ -87,13 +120,46 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
|
|
|
87
120
|
}
|
|
88
121
|
}
|
|
89
122
|
|
|
90
|
-
// Windows and Linux
|
|
123
|
+
// Windows and Linux: set data_directory before proxy_url
|
|
91
124
|
#[cfg(not(target_os = "macos"))]
|
|
92
125
|
{
|
|
93
|
-
window_builder = window_builder
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
126
|
+
window_builder = window_builder.data_directory(_data_dir).theme(None);
|
|
127
|
+
|
|
128
|
+
if !config.proxy_url.is_empty() {
|
|
129
|
+
if let Ok(proxy_url) = Url::from_str(&config.proxy_url) {
|
|
130
|
+
parsed_proxy_url = Some(proxy_url.clone());
|
|
131
|
+
#[cfg(target_os = "windows")]
|
|
132
|
+
{
|
|
133
|
+
if let Some(arg) = build_proxy_browser_arg(&proxy_url) {
|
|
134
|
+
windows_browser_args.push(' ');
|
|
135
|
+
windows_browser_args.push_str(&arg);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
#[cfg(target_os = "windows")]
|
|
142
|
+
{
|
|
143
|
+
window_builder = window_builder.additional_browser_args(&windows_browser_args);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
#[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
|
|
147
|
+
{
|
|
148
|
+
window_builder = window_builder.additional_browser_args(&linux_browser_args);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Set proxy after platform-specific configs (required for Windows/Linux)
|
|
153
|
+
if parsed_proxy_url.is_none() && !config.proxy_url.is_empty() {
|
|
154
|
+
if let Ok(proxy_url) = Url::from_str(&config.proxy_url) {
|
|
155
|
+
parsed_proxy_url = Some(proxy_url);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if let Some(proxy_url) = parsed_proxy_url {
|
|
160
|
+
window_builder = window_builder.proxy_url(proxy_url);
|
|
161
|
+
#[cfg(debug_assertions)]
|
|
162
|
+
println!("Proxy configured: {}", config.proxy_url);
|
|
97
163
|
}
|
|
98
164
|
|
|
99
165
|
window_builder.build().expect("Failed to build window")
|
package/src-tauri/src/lib.rs
CHANGED
|
@@ -24,6 +24,7 @@ pub fn run_app() {
|
|
|
24
24
|
let hide_on_close = pake_config.windows[0].hide_on_close;
|
|
25
25
|
let activation_shortcut = pake_config.windows[0].activation_shortcut.clone();
|
|
26
26
|
let init_fullscreen = pake_config.windows[0].fullscreen;
|
|
27
|
+
let start_to_tray = pake_config.windows[0].start_to_tray && show_system_tray; // Only valid when tray is enabled
|
|
27
28
|
let multi_instance = pake_config.multi_instance;
|
|
28
29
|
|
|
29
30
|
let window_state_plugin = WindowStatePlugin::default()
|
|
@@ -62,15 +63,23 @@ pub fn run_app() {
|
|
|
62
63
|
])
|
|
63
64
|
.setup(move |app| {
|
|
64
65
|
let window = set_window(app, &pake_config, &tauri_config);
|
|
65
|
-
set_system_tray(
|
|
66
|
+
set_system_tray(
|
|
67
|
+
app.app_handle(),
|
|
68
|
+
show_system_tray,
|
|
69
|
+
&pake_config.system_tray_path,
|
|
70
|
+
)
|
|
71
|
+
.unwrap();
|
|
66
72
|
set_global_shortcut(app.app_handle(), activation_shortcut).unwrap();
|
|
67
73
|
|
|
68
74
|
// Show window after state restoration to prevent position flashing
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
// Unless start_to_tray is enabled, then keep it hidden
|
|
76
|
+
if !start_to_tray {
|
|
77
|
+
let window_clone = window.clone();
|
|
78
|
+
tauri::async_runtime::spawn(async move {
|
|
79
|
+
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
|
|
80
|
+
window_clone.show().unwrap();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
74
83
|
|
|
75
84
|
Ok(())
|
|
76
85
|
})
|