diff --git a/.github/workflows/pake-cli.yaml b/.github/workflows/pake-cli.yaml index 3a8a9458d..db0006430 100644 --- a/.github/workflows/pake-cli.yaml +++ b/.github/workflows/pake-cli.yaml @@ -28,8 +28,8 @@ on: description: '[Height, Optional]' required: false default: '780' - transparent: - description: '[Transparent, Optional, MacOS only]' + hide_title_bar: + description: '[Hide TitleBar, Optional, MacOS only]' required: false type: boolean default: false @@ -124,7 +124,7 @@ jobs: ICON: ${{ inputs.icon }} HEIGHT: ${{ inputs.height }} WIDTH: ${{ inputs.width }} - TRANSPARENT: ${{ inputs.transparent }} + HIDE_TITLE_BAR: ${{ inputs.hide_title_bar }} FULLSCREEN: ${{ inputs.fullscreen }} RESIZE: ${{ inputs.resize }} MULTI_ARCH: ${{ inputs.multi_arch }} diff --git a/README.md b/README.md index 7cef3088a..517337a01 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ npm install -g pake-cli pake url [OPTIONS]... # Feel free to play with Pake! It might take a while to prepare the environment the first time you launch Pake. -pake https://weekly.tw93.fun --name Weekly --transparent +pake https://weekly.tw93.fun --name Weekly --hide-title-bar ``` If you are new to the command line, you can compile packages online with _GitHub Actions_. See the [Tutorial]() for more information. @@ -197,7 +197,7 @@ npm run build 1. You can refer to the [codebase structure](https://github.com/tw93/Pake/wiki/Description-of-Pake's-code-structure) before working on Pake, which will help you much in development. 2. Modify the `url` and `productName` fields in the `pake.json` file under the src-tauri directory, the "domain" field in the `tauri.config.json` file needs to be modified synchronously, as well as the `icon` and `identifier` fields in the `tauri.xxx.conf.json` file. You can select an `icon` from the `icons` directory or download one from [macOSicons](https://macosicons.com/#/) to match your product needs. -3. For configurations on window properties, you can modify the `pake.json` file to change the value of `width`, `height`, `fullscreen` (or not), `resizable` (or not) of the `windows` property. To adapt to the immersive header on Mac, change `transparent` to `true`, look for the `Header` element, and add the `padding-top` property. +3. For configurations on window properties, you can modify the `pake.json` file to change the value of `width`, `height`, `fullscreen` (or not), `resizable` (or not) of the `windows` property. To adapt to the immersive header on Mac, change `hideTitleBar` to `true`, look for the `Header` element, and add the `padding-top` property. 4. For advanced usages such as style rewriting, advertisement removal, JS injection, container message communication, and user-defined shortcut keys, see [Advanced Usage of Pake](https://github.com/tw93/Pake/wiki/Advanced-Usage-of-Pake). ## Developers diff --git a/README_CN.md b/README_CN.md index a3c883e4f..7e8726acb 100644 --- a/README_CN.md +++ b/README_CN.md @@ -174,7 +174,7 @@ npm install -g pake-cli pake url [OPTIONS]... # 随便玩玩,首次由于安装环境会有些慢,后面就快了 -pake https://weekly.tw93.fun --name Weekly --transparent +pake https://weekly.tw93.fun --name Weekly --hide-title-bar ``` 假如你不太会使用命令行,或许使用 **GitHub Actions 在线编译多系统版本** 是一个不错的选择,可查看 [文档](https://github.com/tw93/Pake/wiki/%E5%9C%A8%E7%BA%BF%E7%BC%96%E8%AF%91%EF%BC%88%E6%99%AE%E9%80%9A%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%EF%BC%89)。 @@ -199,7 +199,7 @@ npm run build 1. 代码结构可参考 [文档](https://github.com/tw93/Pake/wiki/Pake-%E7%9A%84%E4%BB%A3%E7%A0%81%E7%BB%93%E6%9E%84%E8%AF%B4%E6%98%8E),便于你在开发前了解更多。 2. 修改 src-tauri 目录下 `pake.json` 中的 `url` 和 `productName` 字段,需同步修改下 `tauri.config.json` 中的 `domain` 字段,以及 `tauri.xxx.conf.json` 中的 `icon` 和 `identifier` 字段,其中 `icon` 可以从 icons 目录选择一个,也可以去 [macOSicons](https://macosicons.com/#/) 下载符合效果的。 -3. 关于窗口属性设置,可以在 `pake.json` 修改 windows 属性对应的 `width/height`,fullscreen 是否全屏,resizable 是否可以调整大小,假如想适配 Mac 沉浸式头部,可以将 transparent 设置成 `true`,找到 Header 元素加一个 padding-top 样式即可,不想适配改成 `false` 也行。 +3. 关于窗口属性设置,可以在 `pake.json` 修改 windows 属性对应的 `width/height`,fullscreen 是否全屏,resizable 是否可以调整大小,假如想适配 Mac 沉浸式头部,可以将 hideTitleBar 设置成 `true`,找到 Header 元素加一个 padding-top 样式即可,不想适配改成 `false` 也行。 4. 此外样式改写、屏蔽广告、逻辑代码注入、容器消息通信、自定义快捷键可见 [高级用法](https://github.com/tw93/Pake/wiki/Pake-%E7%9A%84%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95)。 ## 开发者 diff --git a/apps.conf.json b/apps.conf.json index 62f7578f9..b40a876fe 100644 --- a/apps.conf.json +++ b/apps.conf.json @@ -18,12 +18,6 @@ "name_zh": "YouTube", "url": "https://www.youtube.com" }, - { - "name": "reference", - "title": "Reference", - "name_zh": "Reference", - "url": "https://quickref.me/zh-CN/" - }, { "name": "coderunner", "title": "CodeRunner", diff --git a/bin/README.md b/bin/README.md index e0131b759..e7cd21e14 100644 --- a/bin/README.md +++ b/bin/README.md @@ -2,7 +2,7 @@ ## Installation -Ensure that your Node.js version is 16.0 or higher (e.g., 16.8). Avoid using `sudo` for the installation. If you encounter permission issues with npm, refer to [How to fix npm throwing error without sudo](https://stackoverflow.com/questions/16151018/how-to-fix-npm-throwing-error-without-sudo). +Ensure that your Node.js version is 18.0 or higher (e.g., 18.20.2). Avoid using `sudo` for the installation. If you encounter permission issues with npm, refer to [How to fix npm throwing error without sudo](https://stackoverflow.com/questions/16151018/how-to-fix-npm-throwing-error-without-sudo). ```bash npm install pake-cli -g @@ -52,12 +52,11 @@ export const DEFAULT_DEV_PAKE_OPTIONS: PakeCliOptions & {url: string} = { then - ```bash yarn cli:dev ``` -The script will reads the above configuration and packages the specified `app` using `watch` mode, and changes to the `pake-cli` code and `pake` are hot updated in real time. +The script will read the above configuration and packages the specified `app` using `watch` mode, and changes to the `pake-cli` code and `pake` are hot updated in real time. ### CLI Usage @@ -82,7 +81,7 @@ Various options are available for customization. You can pass corresponding argu Specify the application name. If not provided, you will be prompted to enter it. It is recommended to use English. ```shell ---name +--name ``` #### [icon] @@ -113,22 +112,48 @@ Set the width of the application window. Default is `1200px`. --width ``` -#### [transparent] +#### [hide-title-bar] Enable or disable immersive header. Default is `false`. Use the following command to enable this feature, macOS only. ```shell ---transparent +--hide-title-bar ``` #### [fullscreen] -Determine whether the application launches in full screen. Default is `false`. Use the following command to enable full screen. +Determine whether the application launches in full screen. Default is `false`. Use the following command to enable full +screen. ```shell --fullscreen ``` + +#### [activation-shortcut] + +Set the activation shortcut for the application. Default is ` `, it does not take effect, you can customize the activation shortcut with the following commands, e.g. `CmdOrControl+Shift+P`, use can refer to [available-modifiers](https://www.electronjs.org/docs/latest/api/accelerator#available-modifiers). + +```shell +--activation-shortcut +``` + +#### [always-on-top] + +Sets whether the window is always at the top level, defaults to `false`. + +```shell +--always-on-top +``` + +#### [disabled-web-shortcuts] + +Sets whether to disable web shortcuts in the original Pake container, defaults to `false`. + +```shell +--disabled-web-shortcuts +``` + #### [multi-arch] Package the application to support both Intel and M1 chips, exclusively for macOS. Default is `false`. @@ -138,15 +163,15 @@ Package the application to support both Intel and M1 chips, exclusively for macO - Note: After enabling this option, Rust must be installed using rustup from the official Rust website. Installation via brew is not supported. - For Intel chip users, install the arm64 cross-platform package to support M1 chips using the following command: -```shell -rustup target add aarch64-apple-darwin -``` + ```shell + rustup target add aarch64-apple-darwin + ``` - For M1 chip users, install the x86 cross-platform package to support Intel chips using the following command: -```shell -rustup target add x86_64-apple-darwin -``` + ```shell + rustup target add x86_64-apple-darwin + ``` ##### Usage @@ -167,7 +192,7 @@ Select the output package format for Linux. Options include `deb`, `appimage`, o Customize the browser user agent. Default is empty. ```shell ---user-agent +--user-agent ``` #### [show-system-tray] @@ -195,6 +220,7 @@ Enable recursive copying. When the URL is a local file path, enabling this optio ``` #### [inject] + Using `inject`, you can inject local absolute and relative path `css` and `js` files into the page you specify the `url` to customize it. For example, an adblock script that can be applied to any web page, or a `css` that optimizes the `UI` of a page, you can write it once to customize it. would only need to write the `app` once to generalize it to any other page. ```shell @@ -202,15 +228,23 @@ Using `inject`, you can inject local absolute and relative path `css` and `js` f ``` #### [safe-domain] + This secure domain is a domain other than your currently configured `url` to which you may be redirected or jumped to, and only in domains that have been configured as secure can you use `tauri` to expose `api` to browsers to ensure that pake's built-in enhancements work correctly. Only in a domain that has been configured as secure can you use the `tauri` to expose the `api` to the browser, ensuring that `pake's` built-in enhancements work correctly. PS: Secure domains do not need to carry protocols. - ```shell --safe-domain weread.qq.com,google.com ``` +#### [debug] + +The typed package has dev-tools for debugging, in addition to outputting more log messages for debugging. + +```shell +--debug +``` + ## Conclusion After completing the above steps, your application should be successfully packaged. Please note that the packaging process may take some time depending on your system configuration and network conditions. Be patient, and once the packaging is complete, you can find the application installer in the specified directory. diff --git a/bin/README_CN.md b/bin/README_CN.md index f23ef7877..5a0dc0829 100644 --- a/bin/README_CN.md +++ b/bin/README_CN.md @@ -2,7 +2,7 @@ ## 安装 -请确保您的 Node.js 版本为 16 或更高版本(例如 16.8)。请避免使用 `sudo` 进行安装。如果 npm 报告权限问题,请参考 [如何在不使用 sudo 的情况下修复 npm 报错](https://stackoverflow.com/questions/16151018/how-to-fix-npm-throwing-error-without-sudo)。 +请确保您的 Node.js 版本为 18 或更高版本(例如 18.7)。请避免使用 `sudo` 进行安装。如果 npm 报告权限问题,请参考 [如何在不使用 sudo 的情况下修复 npm 报错](https://stackoverflow.com/questions/16151018/how-to-fix-npm-throwing-error-without-sudo)。 ```bash npm install pake-cli -g @@ -40,6 +40,7 @@ npm install pake-cli -g ## 使用方法 ### 开发 + 开发时可以修改 `bin/defaults.ts` 中 `DEFAULT_DEV_PAKE_OPTIONS` 配置,配置项和 `pake-cli` 配置说明保持一致 ```typescript @@ -58,7 +59,6 @@ yarn cli:dev 脚本会读取上述配置并使用 `watch` 模式打包指定的 `app`,对 `pake-cli` 代码和 `pake` 的修改都会实时热更新。 - ### 使用 CLI ```bash @@ -79,10 +79,10 @@ pake [url] [options] #### [name] -指定应用程序的名称。如果在输入时未指定,系统会提示您输入。建议使用英文名称。 +指定应用程序的名称,如果在输入时未指定,系统会提示您输入,建议使用单个英文名称,不要出现下划线或者中文。 ```shell ---name +--name ``` #### [icon] @@ -114,12 +114,12 @@ pake [url] [options] --width ``` -#### [transparent] +#### [hide-title-bar] 设置是否启用沉浸式头部,默认为 `false`(不启用)。当前只对 macOS 上有效。 ```shell ---transparent +--hide-title-bar ``` #### [fullscreen] @@ -130,6 +130,30 @@ pake [url] [options] --fullscreen ``` +#### [activation-shortcut] + +设置应用程序的激活快捷键。默认为空,不生效,可以使用以下命令自定义激活快捷键,例如 `CmdOrControl+Shift+P`,使用可参考 [available-modifiers](https://www.electronjs.org/docs/latest/api/accelerator#available-modifiers)。 + +```shell +--activation-shortcut +``` + +#### [always-on-top] + +设置是否窗口一直在最顶层,默认为 `false`。 + +```shell +--always-on-top +``` + +#### [disabled-web-shortcuts] + +设置是否禁用原有 Pake 容器里面的网页操作快捷键,默认为 `false`。 + +```shell +--disabled-web-shortcuts +``` + #### [multi-arch] 设置打包结果同时支持 Intel 和 M1 芯片,仅适用于 macOS,默认为 `false`。 @@ -139,15 +163,15 @@ pake [url] [options] - 注意:启用此选项后,需要使用 rust 官网的 rustup 安装 rust,不支持通过 brew 安装。 - 对于 Intel 芯片用户,需要安装 arm64 跨平台包,以使安装包支持 M1 芯片。使用以下命令安装: -```shell -rustup target add aarch64-apple-darwin -``` + ```shell + rustup target add aarch64-apple-darwin + ``` - 对于 M1 芯片用户,需要安装 x86 跨平台包,以使安装包支持 Intel 芯片。使用以下命令安装: -```shell -rustup target add x86_64-apple-darwin -``` + ```shell + rustup target add x86_64-apple-darwin + ``` ##### 使用方法 @@ -161,7 +185,7 @@ rustup target add x86_64-apple-darwin Linux,默认为 `all`。 ```shell ---targets +--targets ``` #### [user-agent] @@ -169,7 +193,7 @@ Linux,默认为 `all`。 自定义浏览器的用户代理请求头,默认为空。 ```shell ---user-agent +--user-agent ``` #### [show-system-tray] @@ -222,6 +246,14 @@ PS: 安全域名不需要携带协议。 --safe-domain weread.qq.com,google.com ``` +#### [debug] + +打出来的包具备 deb-tools 的调试模式,此外还会输出更多的日志信息用于调试。 + +```shell +--debug +``` + ## 结语 完成上述步骤后,您的应用程序应该已经成功打包。请注意,根据您的系统配置和网络状况,打包过程可能需要一些时间。请耐心等待,一旦打包完成,您就可以在指定的目录中找到应用程序安装包。 diff --git a/bin/builders/BaseBuilder.ts b/bin/builders/BaseBuilder.ts index 608e4b708..ec679db74 100644 --- a/bin/builders/BaseBuilder.ts +++ b/bin/builders/BaseBuilder.ts @@ -49,7 +49,7 @@ export default abstract class BaseBuilder { const isChina = await isChinaDomain('www.npmjs.com'); const spinner = getSpinner('Installing package...'); const rustProjectDir = path.join(tauriSrcPath, '.cargo'); - const projectConf = path.join(rustProjectDir, 'config'); + const projectConf = path.join(rustProjectDir, 'config.toml'); await fsExtra.ensureDir(rustProjectDir); if (isChina) { @@ -73,7 +73,7 @@ export default abstract class BaseBuilder { async start(url: string) { await mergeConfig(url, this.options, tauriConfig); - } + } async buildAndCopy(url: string, target: string) { const { name } = this.options; @@ -107,7 +107,8 @@ export default abstract class BaseBuilder { } protected getBasePath(): string { - return 'src-tauri/target/release/bundle/'; + const basePath = this.options.debug ? 'debug' : 'release'; + return `src-tauri/target/${basePath}/bundle/`; } protected getBuildAppPath(npmDirectory: string, fileName: string, fileType: string): string { diff --git a/bin/cli.ts b/bin/cli.ts index 6c87d59e5..be4b2f6ad 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -1,5 +1,5 @@ import chalk from 'chalk'; -import { program } from 'commander'; +import { program, Option } from 'commander'; import log from 'loglevel'; import packageJson from '../package.json'; import BuilderProvider from './builders/BuilderProvider'; @@ -10,7 +10,7 @@ import handleInputOptions from './options/index'; import { PakeCliOptions } from './types'; import { validateNumberInput, validateUrlInput } from './utils/validate'; -const { green, yellow }= chalk; +const { green, yellow } = chalk; const logo = `${chalk.green(' ____ _')} ${green('| _ \\ __ _| | _____')} ${green('| |_) / _` | |/ / _ \\')} @@ -29,17 +29,19 @@ program .option('--icon ', 'Application icon', DEFAULT.icon) .option('--width ', 'Window width', validateNumberInput, DEFAULT.width) .option('--height ', 'Window height', validateNumberInput, DEFAULT.height) - .option('--transparent', 'Only for Mac, hide title bar', DEFAULT.transparent) .option('--fullscreen', 'Start in full screen', DEFAULT.fullscreen) - .option('--user-agent ', 'Custom user agent', DEFAULT.userAgent) - .option('--show-system-tray', 'Show system tray in app', DEFAULT.showSystemTray) - .option('--system-tray-icon ', 'Custom system tray icon', DEFAULT.systemTrayIcon) - .option('--iter-copy-file', 'Copy files when URL is a local file', DEFAULT.iterCopyFile) + .option('--hide-title-bar', 'Only for Mac, hide title bar', DEFAULT.hideTitleBar) + .option('--activation-shortcut ', 'Shortcut key to active App', DEFAULT.activationShortcut) .option('--multi-arch', 'Only for Mac, supports both Intel and M1', DEFAULT.multiArch) - .option('--targets ', 'Only for Linux, option "deb" or "appimage"', DEFAULT.targets) .option('--inject [injects...]', 'Injection of .js or .css Files', DEFAULT.inject) .option('--safe-domain [domains...]', 'Domains that Require Security Configuration"', DEFAULT.safeDomain) - .option('--debug', 'Debug mode', DEFAULT.debug) + .option('--debug', 'Debug build and more output', DEFAULT.debug) + .addOption(new Option('--user-agent ', 'Custom user agent').default(DEFAULT.userAgent).hideHelp()) + .addOption(new Option('--targets ', 'Only for Linux, option "deb" or "appimage"').default(DEFAULT.targets).hideHelp()) + .addOption(new Option('--always-on-top', 'Always on the top level').default(DEFAULT.alwaysOnTop).hideHelp()) + .addOption(new Option('--disabled-web-shortcuts', 'Disabled webPage shortcuts').default(DEFAULT.disabledWebShortcuts).hideHelp()) + .addOption(new Option('--show-system-tray', 'Show system tray in app').default(DEFAULT.showSystemTray).hideHelp()) + .addOption(new Option('--system-tray-icon ', 'Custom system tray icon').default(DEFAULT.systemTrayIcon).hideHelp()) .version(packageJson.version, '-v, --version', 'Output the current version') .action(async (url: string, options: PakeCliOptions) => { await checkUpdateTips(); diff --git a/bin/defaults.ts b/bin/defaults.ts index 8403d8901..ef356da53 100644 --- a/bin/defaults.ts +++ b/bin/defaults.ts @@ -6,7 +6,10 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = { width: 1200, fullscreen: false, resizable: true, - transparent: false, + hideTitleBar: false, + alwaysOnTop: false, + disabledWebShortcuts: false, + activationShortcut: '', userAgent: '', showSystemTray: false, multiArch: false, @@ -19,10 +22,10 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = { }; // Just for cli development -export const DEFAULT_DEV_PAKE_OPTIONS: PakeCliOptions & {url: string} = { +export const DEFAULT_DEV_PAKE_OPTIONS: PakeCliOptions & { url: string } = { ...DEFAULT_PAKE_OPTIONS, url: 'https://weread.qq.com', name: 'WeRead', - safeDomain:['weread.qq.com'], - transparent: true, -} + safeDomain: ['weread.qq.com'], + hideTitleBar: true, +}; diff --git a/bin/helpers/merge.ts b/bin/helpers/merge.ts index 6883dea56..e1a30e68f 100644 --- a/bin/helpers/merge.ts +++ b/bin/helpers/merge.ts @@ -12,7 +12,10 @@ export async function mergeConfig(url: string, options: PakeAppOptions, tauriCon width, height, fullscreen, - transparent, + hideTitleBar, + alwaysOnTop, + disabledWebShortcuts, + activationShortcut, userAgent, showSystemTray, systemTrayIcon, @@ -31,8 +34,11 @@ export async function mergeConfig(url: string, options: PakeAppOptions, tauriCon width, height, fullscreen, - transparent, resizable, + hide_title_bar: hideTitleBar, + activation_shortcut: activationShortcut, + always_on_top: alwaysOnTop, + disabled_web_shortcuts: disabledWebShortcuts, }; Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions }); @@ -191,7 +197,7 @@ export async function mergeConfig(url: string, options: PakeAppOptions, tauriCon logger.error('The injected file must be in either CSS or JS format.'); return; } - const files = inject.map(filepath => path.isAbsolute(filepath) ? filepath : path.join(process.cwd(), filepath)); + const files = inject.map(filepath => path.isAbsolute(filepath) ? filepath : path.join(process.cwd(), filepath)); tauriConf.pake.inject = files; await combineFiles(files, injectFilePath); } else { diff --git a/bin/types.ts b/bin/types.ts index 74e2b5856..f1eda575a 100644 --- a/bin/types.ts +++ b/bin/types.ts @@ -21,8 +21,17 @@ export interface PakeCliOptions { // Whether the window can be fullscreen, default false fullscreen: boolean; - // Enable immersive header, default false - transparent: boolean; + // Enable immersive header, default false. + hideTitleBar: boolean; + + // Enable windows always on top, default false + alwaysOnTop: boolean; + + // Disable web shortcuts, default false + disabledWebShortcuts: boolean; + + // Set a shortcut key to wake up the app, default empty + activationShortcut: string; // Custom User-Agent, default off userAgent: string; diff --git a/dist/cli.js b/dist/cli.js index 046be55da..9478f3c2c 100644 --- a/dist/cli.js +++ b/dist/cli.js @@ -1,5 +1,5 @@ import chalk from 'chalk'; -import { InvalidArgumentError, program } from 'commander'; +import { InvalidArgumentError, program, Option } from 'commander'; import log from 'loglevel'; import path from 'path'; import fsExtra from 'fs-extra'; @@ -20,7 +20,7 @@ import psl from 'psl'; import isUrl from 'is-url'; var name = "pake-cli"; -var version = "2.3.8"; +var version = "2.4.0"; var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。"; var engines = { node: ">=16.0.0" @@ -126,12 +126,15 @@ var packageJson = { var windows = [ { url: "https://weread.qq.com", - transparent: true, + url_type: "web", + hide_title_bar: true, fullscreen: false, width: 1200, height: 780, resizable: true, - url_type: "web" + always_on_top: false, + activation_shortcut: "", + disabled_web_shortcuts: false } ]; var user_agent = { @@ -471,15 +474,18 @@ async function combineFiles(files, output) { } async function mergeConfig(url, options, tauriConf) { - const { width, height, fullscreen, transparent, userAgent, showSystemTray, systemTrayIcon, iterCopyFile, identifier, name, resizable = true, inject, safeDomain, } = options; + const { width, height, fullscreen, hideTitleBar, alwaysOnTop, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, iterCopyFile, identifier, name, resizable = true, inject, safeDomain, } = options; const { platform } = process; // Set Windows parameters. const tauriConfWindowOptions = { width, height, fullscreen, - transparent, resizable, + hide_title_bar: hideTitleBar, + activation_shortcut: activationShortcut, + always_on_top: alwaysOnTop, + disabled_web_shortcuts: disabledWebShortcuts, }; Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions }); tauriConf.package.productName = name; @@ -682,7 +688,7 @@ class BaseBuilder { const isChina = await isChinaDomain('www.npmjs.com'); const spinner = getSpinner('Installing package...'); const rustProjectDir = path.join(tauriSrcPath, '.cargo'); - const projectConf = path.join(rustProjectDir, 'config'); + const projectConf = path.join(rustProjectDir, 'config.toml'); await fsExtra.ensureDir(rustProjectDir); if (isChina) { logger.info('✺ Located in China, using npm/rsProxy CN mirror.'); @@ -729,7 +735,8 @@ class BaseBuilder { return this.options.debug ? 'npm run build:debug' : 'npm run build'; } getBasePath() { - return 'src-tauri/target/release/bundle/'; + const basePath = this.options.debug ? 'debug' : 'release'; + return `src-tauri/target/${basePath}/bundle/`; } getBuildAppPath(npmDirectory, fileName, fileType) { return path.join(npmDirectory, this.getBasePath(), fileType.toLowerCase(), `${fileName}.${fileType}`); @@ -823,7 +830,10 @@ const DEFAULT_PAKE_OPTIONS = { width: 1200, fullscreen: false, resizable: true, - transparent: false, + hideTitleBar: false, + alwaysOnTop: false, + disabledWebShortcuts: false, + activationShortcut: '', userAgent: '', showSystemTray: false, multiArch: false, @@ -1014,17 +1024,19 @@ program .option('--icon ', 'Application icon', DEFAULT_PAKE_OPTIONS.icon) .option('--width ', 'Window width', validateNumberInput, DEFAULT_PAKE_OPTIONS.width) .option('--height ', 'Window height', validateNumberInput, DEFAULT_PAKE_OPTIONS.height) - .option('--transparent', 'Only for Mac, hide title bar', DEFAULT_PAKE_OPTIONS.transparent) .option('--fullscreen', 'Start in full screen', DEFAULT_PAKE_OPTIONS.fullscreen) - .option('--user-agent ', 'Custom user agent', DEFAULT_PAKE_OPTIONS.userAgent) - .option('--show-system-tray', 'Show system tray in app', DEFAULT_PAKE_OPTIONS.showSystemTray) - .option('--system-tray-icon ', 'Custom system tray icon', DEFAULT_PAKE_OPTIONS.systemTrayIcon) - .option('--iter-copy-file', 'Copy files when URL is a local file', DEFAULT_PAKE_OPTIONS.iterCopyFile) + .option('--hide-title-bar', 'Only for Mac, hide title bar', DEFAULT_PAKE_OPTIONS.hideTitleBar) + .option('--activation-shortcut ', 'Shortcut key to active App', DEFAULT_PAKE_OPTIONS.activationShortcut) .option('--multi-arch', 'Only for Mac, supports both Intel and M1', DEFAULT_PAKE_OPTIONS.multiArch) - .option('--targets ', 'Only for Linux, option "deb" or "appimage"', DEFAULT_PAKE_OPTIONS.targets) .option('--inject [injects...]', 'Injection of .js or .css Files', DEFAULT_PAKE_OPTIONS.inject) .option('--safe-domain [domains...]', 'Domains that Require Security Configuration"', DEFAULT_PAKE_OPTIONS.safeDomain) - .option('--debug', 'Debug mode', DEFAULT_PAKE_OPTIONS.debug) + .option('--debug', 'Debug build and more output', DEFAULT_PAKE_OPTIONS.debug) + .addOption(new Option('--user-agent ', 'Custom user agent').default(DEFAULT_PAKE_OPTIONS.userAgent).hideHelp()) + .addOption(new Option('--targets ', 'Only for Linux, option "deb" or "appimage"').default(DEFAULT_PAKE_OPTIONS.targets).hideHelp()) + .addOption(new Option('--always-on-top', 'Always on the top level').default(DEFAULT_PAKE_OPTIONS.alwaysOnTop).hideHelp()) + .addOption(new Option('--disabled-web-shortcuts', 'Disabled webPage shortcuts').default(DEFAULT_PAKE_OPTIONS.disabledWebShortcuts).hideHelp()) + .addOption(new Option('--show-system-tray', 'Show system tray in app').default(DEFAULT_PAKE_OPTIONS.showSystemTray).hideHelp()) + .addOption(new Option('--system-tray-icon ', 'Custom system tray icon').default(DEFAULT_PAKE_OPTIONS.systemTrayIcon).hideHelp()) .version(packageJson.version, '-v, --version', 'Output the current version') .action(async (url, options) => { await checkUpdateTips(); diff --git a/package.json b/package.json index 8073af20a..03a725632 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pake-cli", - "version": "2.3.8", + "version": "2.4.0", "description": "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。", "engines": { "node": ">=16.0.0" diff --git a/script/build_with_pake_cli.js b/script/build_with_pake_cli.js index fede4d0cb..621eec833 100644 --- a/script/build_with_pake_cli.js +++ b/script/build_with_pake_cli.js @@ -13,7 +13,7 @@ console.log('name: ', process.env.NAME); console.log('icon: ', process.env.ICON); console.log('height: ', process.env.HEIGHT); console.log('width: ', process.env.WIDTH); -console.log('transparent: ', process.env.TRANSPARENT); +console.log('hide-title-bar: ', process.env.HIDE_TITLE_BAR); console.log('resize: ', process.env.RESIZE); console.log('is multi arch? only for Mac: ', process.env.MULTI_ARCH); console.log('targets type? only for Linux: ', process.env.TARGETS); @@ -22,8 +22,8 @@ console.log('===========================\n'); cd('node_modules/pake-cli'); let params = `node cli.js ${process.env.URL} --name ${process.env.NAME} --height ${process.env.HEIGHT} --width ${process.env.WIDTH}`; -if (process.env.TRANSPARENT === 'true') { - params = `${params} --transparent`; +if (process.env.HIDE_TITLE_BAR === 'true') { + params = `${params} --hide-title-bar`; } if (process.env.FULLSCREEN === 'true') { diff --git a/src-tauri/pake.json b/src-tauri/pake.json index 9d36efe51..382b34b04 100644 --- a/src-tauri/pake.json +++ b/src-tauri/pake.json @@ -2,12 +2,15 @@ "windows": [ { "url": "https://weread.qq.com", - "transparent": true, + "url_type": "web", + "hide_title_bar": true, "fullscreen": false, "width": 1200, "height": 780, "resizable": true, - "url_type": "web" + "always_on_top": false, + "activation_shortcut": "", + "disabled_web_shortcuts": false } ], "user_agent": { diff --git a/src-tauri/rust_proxy.toml b/src-tauri/rust_proxy.toml index dbd564d3d..e5ab56226 100644 --- a/src-tauri/rust_proxy.toml +++ b/src-tauri/rust_proxy.toml @@ -1,14 +1,10 @@ [source.crates-io] -# To use sparse index, change 'rsproxy' to 'rsproxy-sparse' -replace-with = 'rsproxy' - +replace-with = 'rsproxy-sparse' [source.rsproxy] registry = "https://rsproxy.cn/crates.io-index" [source.rsproxy-sparse] registry = "sparse+https://rsproxy.cn/index/" - [registries.rsproxy] index = "https://rsproxy.cn/crates.io-index" - [net] git-fetch-with-cli = true diff --git a/src-tauri/src/app/config.rs b/src-tauri/src/app/config.rs index 1460ca8cb..528087583 100644 --- a/src-tauri/src/app/config.rs +++ b/src-tauri/src/app/config.rs @@ -1,17 +1,20 @@ -use serde::Deserialize; +use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct WindowConfig { pub url: String, - pub transparent: bool, + pub hide_title_bar: bool, pub fullscreen: bool, pub width: f64, pub height: f64, pub resizable: bool, pub url_type: String, + pub always_on_top: bool, + pub disabled_web_shortcuts: bool, + pub activation_shortcut: String, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct PlatformSpecific { pub macos: T, pub linux: T, @@ -43,7 +46,7 @@ where pub type UserAgent = PlatformSpecific; pub type FunctionON = PlatformSpecific; -#[derive(Debug, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct PakeConfig { pub windows: Vec, pub user_agent: UserAgent, diff --git a/src-tauri/src/app/menu.rs b/src-tauri/src/app/menu.rs index 47f191adb..0d03dd6cc 100644 --- a/src-tauri/src/app/menu.rs +++ b/src-tauri/src/app/menu.rs @@ -1,4 +1,4 @@ -use tauri::{CustomMenuItem,Manager, SystemTray, SystemTrayEvent, SystemTrayMenu}; +use tauri::{CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu}; use tauri_plugin_window_state::{AppHandleExt, StateFlags}; pub fn get_system_tray() -> SystemTray { diff --git a/src-tauri/src/app/window.rs b/src-tauri/src/app/window.rs index 64c5db984..44cdf849c 100644 --- a/src-tauri/src/app/window.rs +++ b/src-tauri/src/app/window.rs @@ -19,6 +19,11 @@ pub fn get_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wind _ => panic!("url type can only be web or local"), }; + let config_script = format!( + "window.pakeConfig = {}", + serde_json::to_string(&window_config).unwrap() + ); + let mut window_builder = WindowBuilder::new(app, "pake", url) .title("") .user_agent(user_agent) @@ -27,21 +32,17 @@ pub fn get_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wind .fullscreen(window_config.fullscreen) .inner_size(window_config.width, window_config.height) .disable_file_drop_handler() + .always_on_top(window_config.always_on_top) + .initialization_script(&config_script) .initialization_script(include_str!("../inject/component.js")) .initialization_script(include_str!("../inject/event.js")) .initialization_script(include_str!("../inject/style.js")) //This is necessary to allow for file injection by external developers for customization purposes. .initialization_script(include_str!("../inject/custom.js")); - // For dynamic display of header styles - if window_config.transparent { - let transparent_script = "window.pakeWindowTitleTransparent = true;"; - window_builder = window_builder.initialization_script(transparent_script); - } - #[cfg(target_os = "macos")] { - let title_bar_style = if window_config.transparent { + let title_bar_style = if window_config.hide_title_bar { TitleBarStyle::Overlay } else { TitleBarStyle::Visible diff --git a/src-tauri/src/inject/event.js b/src-tauri/src/inject/event.js index 31ae81f02..d3131eaf6 100644 --- a/src-tauri/src/inject/event.js +++ b/src-tauri/src/inject/event.js @@ -63,7 +63,7 @@ document.addEventListener('DOMContentLoaded', () => { const appWindow = tauri.window.appWindow; const invoke = tauri.tauri.invoke; - if(!document.getElementById('pake-top-dom')){ + if (!document.getElementById('pake-top-dom')) { const topDom = document.createElement('div'); topDom.id = 'pake-top-dom'; document.body.appendChild(topDom); @@ -88,14 +88,16 @@ document.addEventListener('DOMContentLoaded', () => { }); }); - document.addEventListener('keyup', (event) => { - if (/windows|linux/i.test(navigator.userAgent) && event.ctrlKey) { - handleShortcut(event); - } - if (/macintosh|mac os x/i.test(navigator.userAgent) && event.metaKey) { - handleShortcut(event); - } - }); + if (window['pakeConfig']?.disabled_web_shortcuts !== true) { + document.addEventListener('keyup', (event) => { + if (/windows|linux/i.test(navigator.userAgent) && event.ctrlKey) { + handleShortcut(event); + } + if (/macintosh|mac os x/i.test(navigator.userAgent) && event.metaKey) { + handleShortcut(event); + } + }); + } // Collect blob urls to blob by overriding window.URL.createObjectURL function collectUrlToBlobs() { diff --git a/src-tauri/src/inject/style.js b/src-tauri/src/inject/style.js index 62da1a7b7..816963e08 100644 --- a/src-tauri/src/inject/style.js +++ b/src-tauri/src/inject/style.js @@ -412,7 +412,7 @@ window.addEventListener('DOMContentLoaded', _event => { } `; const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; - if (window.pakeWindowTitleTransparent && isMac) { + if (window['pakeConfig']?.hide_title_bar && isMac) { const topPaddingStyleElement = document.createElement('style'); topPaddingStyleElement.innerHTML = topPaddingCSS; document.head.appendChild(topPaddingStyleElement); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index aa9eb704f..0570dab38 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,14 +1,15 @@ #![cfg_attr( -all(not(debug_assertions), target_os = "windows"), -windows_subsystem = "windows" + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" )] mod app; mod util; -use app::{invoke, window, menu}; +use app::{invoke, menu, window}; use invoke::{download_file, download_file_by_binary}; use menu::{get_system_tray, system_tray_handle}; +use tauri::{GlobalShortcutManager, Manager}; use tauri_plugin_window_state::Builder as windowStatePlugin; use util::{get_data_dir, get_pake_config}; use window::get_window; @@ -28,6 +29,9 @@ pub fn run_app() { .on_system_tray_event(system_tray_handle); } + // Save the value of toggle_app_shortcut before pake_config is moved + let activation_shortcut = pake_config.windows[0].activation_shortcut.clone(); + tauri_app .plugin(windowStatePlugin::default().build()) .plugin(tauri_plugin_oauth::init()) @@ -35,10 +39,28 @@ pub fn run_app() { download_file, download_file_by_binary ]) - .setup(|app| { + .setup(move |app| { let _window = get_window(app, pake_config, data_dir); // Prevent initial shaking _window.show().unwrap(); + + if !activation_shortcut.is_empty() { + let app_handle = app.app_handle().clone(); + app_handle + .global_shortcut_manager() + .register(activation_shortcut.as_str(), move || { + let window = app_handle.get_window("pake").unwrap(); + match window.is_visible().unwrap() { + true => window.hide().unwrap(), + false => { + window.show().unwrap(); + window.set_focus().unwrap(); + } + } + }) + .expect("Error registering global evoke shortcuts!"); + } + Ok(()) }) .on_window_event(|event| { diff --git a/src-tauri/src/util.rs b/src-tauri/src/util.rs index 4b82e876a..ec8242f66 100644 --- a/src-tauri/src/util.rs +++ b/src-tauri/src/util.rs @@ -7,12 +7,15 @@ pub fn get_pake_config() -> (PakeConfig, Config) { #[cfg(feature = "cli-build")] let pake_config: PakeConfig = serde_json::from_str(include_str!("../.pake/pake.json")) .expect("Failed to parse pake config"); + #[cfg(not(feature = "cli-build"))] let pake_config: PakeConfig = serde_json::from_str(include_str!("../pake.json")).expect("Failed to parse pake config"); + #[cfg(feature = "cli-build")] let tauri_config: Config = serde_json::from_str(include_str!("../.pake/tauri.conf.json")) .expect("Failed to parse tauri config"); + #[cfg(not(feature = "cli-build"))] let tauri_config: Config = serde_json::from_str(include_str!("../tauri.conf.json")) .expect("Failed to parse tauri config");