diff --git a/desktop/angular/package-lock.json b/desktop/angular/package-lock.json index 6709037cb..b8527c1da 100644 --- a/desktop/angular/package-lock.json +++ b/desktop/angular/package-lock.json @@ -23,13 +23,13 @@ "@fortawesome/free-brands-svg-icons": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0", "@fortawesome/free-solid-svg-icons": "^6.4.0", - "@tauri-apps/api": ">=2.0.0-beta.0", - "@tauri-apps/plugin-cli": ">=2.0.0-beta.0", - "@tauri-apps/plugin-clipboard-manager": ">=2.0.0-beta.0", - "@tauri-apps/plugin-dialog": ">=2.0.0-beta.0", - "@tauri-apps/plugin-notification": ">=2.0.0-beta.0", - "@tauri-apps/plugin-os": ">=2.0.0-beta.0", - "@tauri-apps/plugin-shell": "^2.0.0-beta", + "@tauri-apps/api": ">=2.0.0-rc.1", + "@tauri-apps/plugin-cli": ">=2.0.0-rc.1", + "@tauri-apps/plugin-clipboard-manager": ">=2.0.0-rc.1", + "@tauri-apps/plugin-dialog": ">=2.0.0-rc.1", + "@tauri-apps/plugin-notification": ">=2.0.0-rc.1", + "@tauri-apps/plugin-os": ">=2.0.0-rc.1", + "@tauri-apps/plugin-shell": "^2.0.0-rc", "autoprefixer": "^10.4.14", "d3": "^7.8.4", "data-urls": "^5.0.0", @@ -4406,77 +4406,67 @@ "peer": true }, "node_modules/@tauri-apps/api": { - "version": "2.0.0-beta.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-beta.4.tgz", - "integrity": "sha512-Nxtj28NYUo5iwYkpYslxmOPkdI2WkELU2e3UH9nbJm9Ydki2CQwJVGQxx4EANtdZcMNsEsUzRqaDTvEUYH1l6w==", - "engines": { - "node": ">= 18", - "npm": ">= 6.6.0", - "yarn": ">= 1.19.1" - }, + "version": "2.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.4.tgz", + "integrity": "sha512-UNiIhhKG08j4ooss2oEEVexffmWkgkYlC2M3GcX3VPtNsqFgVNL8Mcw/4Y7rO9M9S+ffAMnLOF5ypzyuyb8tyg==", + "license": "Apache-2.0 OR MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/tauri" } }, "node_modules/@tauri-apps/plugin-cli": { - "version": "2.0.0-beta.1", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0-rc.1.tgz", + "integrity": "sha512-EcSTRfEU3zzlNbgwVtZVzqB19z3PNjyXD9H+YXuuLpV+Hwuh6Oi1fhUdCI0mp5zr9HSMWE+HzHkpBI7sVP1RyA==", "license": "MIT or APACHE-2.0", "dependencies": { - "@tauri-apps/api": "2.0.0-beta.2" - } - }, - "node_modules/@tauri-apps/plugin-cli/node_modules/@tauri-apps/api": { - "version": "2.0.0-beta.2", - "license": "Apache-2.0 OR MIT", - "engines": { - "node": ">= 18", - "npm": ">= 6.6.0", - "yarn": ">= 1.19.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/tauri" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "node_modules/@tauri-apps/plugin-clipboard-manager": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-beta.2.tgz", - "integrity": "sha512-yue7KTO9r9rlpgjcyRB9xcMyZKTrGOP2bWQnL/EoyVkECsr+8e8W8UMlvajXjv1hinFoiycXJe6GaSTPGO0Jlg==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-rc.1.tgz", + "integrity": "sha512-hFgUABMmQuVGKwHb8PR9fuqfk0WRkedbWUt/ZV5sL4Q6kLrsp3JYJvtzVPeMYdeBvMqHl8WXNxAc/zwSld2h9w==", + "license": "MIT or APACHE-2.0", "dependencies": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "node_modules/@tauri-apps/plugin-dialog": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-beta.2.tgz", - "integrity": "sha512-WugTn/8d5jYA0GL1JRIJgA1OSxG0h2V4PSZZzehgA3v7rPlIU6w9s2+dSRqj55aMj6hm3Az9YbQqC18nuaHkpw==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.1.tgz", + "integrity": "sha512-H28gh6BfZtjflHQ+HrmWwunDriBI3AQLAKnMs50GA6zeNUULqbQr7VXbAAKeJL/0CmWcecID4PKXVoSlaWRhEg==", + "license": "MIT or APACHE-2.0", "dependencies": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "node_modules/@tauri-apps/plugin-notification": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0-beta.2.tgz", - "integrity": "sha512-OxMuKawWkXGR04hALFrPhRXhA3vGRyMy+kRT3vdHoAwngZHcBGetRqm6CuW0tSNWCgwuUYXpN57636CfUReg5g==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0-rc.1.tgz", + "integrity": "sha512-ddDj7xM8XR7Zv2vdpofNXlLjcp49p/VjlL0D+/eBcMuyooaLNMor3jz/+H6s23iHerdxMWA50mzy26BRN1BySA==", + "license": "MIT or APACHE-2.0", "dependencies": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "node_modules/@tauri-apps/plugin-os": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-beta.2.tgz", - "integrity": "sha512-rhJ/sEYvEAeMUQt6UiFODi5dT6F/ciNZYBQrbFTwhIqwQ2fp87dmzsscMy7FQ9LOor8AW+kL1KWoadfgzA/mSA==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-rc.1.tgz", + "integrity": "sha512-PV8zlSTmYfiN2xzILUmlDSEycS7UYbH2yXk/ZqF+qQU6/s+OVQvmSth4EhllFjcpvPbtqELvpzfjw+2qEouchA==", + "license": "MIT or APACHE-2.0", "dependencies": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "node_modules/@tauri-apps/plugin-shell": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-beta.2.tgz", - "integrity": "sha512-9rWsfN7Wt+EuWmpmNnK8bCs+04fzhEYrHtWyLIAYxb9diFdcJrEoctCP9YM2v+Uf8/y8qFC7VCbZ/9VQHANymQ==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.1.tgz", + "integrity": "sha512-JtNROc0rqEwN/g93ig5pK4cl1vUo2yn+osCpY9de64cy/d9hRzof7AuYOgvt/Xcd5VPQmlgo2AGvUh5sQRSR1A==", + "license": "MIT or APACHE-2.0", "dependencies": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "node_modules/@tootallnate/once": { @@ -21077,59 +21067,56 @@ "peer": true }, "@tauri-apps/api": { - "version": "2.0.0-beta.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-beta.4.tgz", - "integrity": "sha512-Nxtj28NYUo5iwYkpYslxmOPkdI2WkELU2e3UH9nbJm9Ydki2CQwJVGQxx4EANtdZcMNsEsUzRqaDTvEUYH1l6w==" + "version": "2.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.4.tgz", + "integrity": "sha512-UNiIhhKG08j4ooss2oEEVexffmWkgkYlC2M3GcX3VPtNsqFgVNL8Mcw/4Y7rO9M9S+ffAMnLOF5ypzyuyb8tyg==" }, "@tauri-apps/plugin-cli": { - "version": "2.0.0-beta.1", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-cli/-/plugin-cli-2.0.0-rc.1.tgz", + "integrity": "sha512-EcSTRfEU3zzlNbgwVtZVzqB19z3PNjyXD9H+YXuuLpV+Hwuh6Oi1fhUdCI0mp5zr9HSMWE+HzHkpBI7sVP1RyA==", "requires": { - "@tauri-apps/api": "2.0.0-beta.2" - }, - "dependencies": { - "@tauri-apps/api": { - "version": "2.0.0-beta.2" - } + "@tauri-apps/api": "^2.0.0-rc.4" } }, "@tauri-apps/plugin-clipboard-manager": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-beta.2.tgz", - "integrity": "sha512-yue7KTO9r9rlpgjcyRB9xcMyZKTrGOP2bWQnL/EoyVkECsr+8e8W8UMlvajXjv1hinFoiycXJe6GaSTPGO0Jlg==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-rc.1.tgz", + "integrity": "sha512-hFgUABMmQuVGKwHb8PR9fuqfk0WRkedbWUt/ZV5sL4Q6kLrsp3JYJvtzVPeMYdeBvMqHl8WXNxAc/zwSld2h9w==", "requires": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "@tauri-apps/plugin-dialog": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-beta.2.tgz", - "integrity": "sha512-WugTn/8d5jYA0GL1JRIJgA1OSxG0h2V4PSZZzehgA3v7rPlIU6w9s2+dSRqj55aMj6hm3Az9YbQqC18nuaHkpw==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.1.tgz", + "integrity": "sha512-H28gh6BfZtjflHQ+HrmWwunDriBI3AQLAKnMs50GA6zeNUULqbQr7VXbAAKeJL/0CmWcecID4PKXVoSlaWRhEg==", "requires": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "@tauri-apps/plugin-notification": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0-beta.2.tgz", - "integrity": "sha512-OxMuKawWkXGR04hALFrPhRXhA3vGRyMy+kRT3vdHoAwngZHcBGetRqm6CuW0tSNWCgwuUYXpN57636CfUReg5g==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.0.0-rc.1.tgz", + "integrity": "sha512-ddDj7xM8XR7Zv2vdpofNXlLjcp49p/VjlL0D+/eBcMuyooaLNMor3jz/+H6s23iHerdxMWA50mzy26BRN1BySA==", "requires": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "@tauri-apps/plugin-os": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-beta.2.tgz", - "integrity": "sha512-rhJ/sEYvEAeMUQt6UiFODi5dT6F/ciNZYBQrbFTwhIqwQ2fp87dmzsscMy7FQ9LOor8AW+kL1KWoadfgzA/mSA==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-rc.1.tgz", + "integrity": "sha512-PV8zlSTmYfiN2xzILUmlDSEycS7UYbH2yXk/ZqF+qQU6/s+OVQvmSth4EhllFjcpvPbtqELvpzfjw+2qEouchA==", "requires": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "@tauri-apps/plugin-shell": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-beta.2.tgz", - "integrity": "sha512-9rWsfN7Wt+EuWmpmNnK8bCs+04fzhEYrHtWyLIAYxb9diFdcJrEoctCP9YM2v+Uf8/y8qFC7VCbZ/9VQHANymQ==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.1.tgz", + "integrity": "sha512-JtNROc0rqEwN/g93ig5pK4cl1vUo2yn+osCpY9de64cy/d9hRzof7AuYOgvt/Xcd5VPQmlgo2AGvUh5sQRSR1A==", "requires": { - "@tauri-apps/api": "2.0.0-beta.4" + "@tauri-apps/api": "^2.0.0-rc.4" } }, "@tootallnate/once": { diff --git a/desktop/angular/package.json b/desktop/angular/package.json index f54fdfa75..5e916e511 100644 --- a/desktop/angular/package.json +++ b/desktop/angular/package.json @@ -37,13 +37,13 @@ "@fortawesome/free-brands-svg-icons": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0", "@fortawesome/free-solid-svg-icons": "^6.4.0", - "@tauri-apps/api": ">=2.0.0-beta.0", - "@tauri-apps/plugin-cli": ">=2.0.0-beta.0", - "@tauri-apps/plugin-clipboard-manager": ">=2.0.0-beta.0", - "@tauri-apps/plugin-dialog": ">=2.0.0-beta.0", - "@tauri-apps/plugin-notification": ">=2.0.0-beta.0", - "@tauri-apps/plugin-os": ">=2.0.0-beta.0", - "@tauri-apps/plugin-shell": "^2.0.0-beta", + "@tauri-apps/api": ">=2.0.0-rc.1", + "@tauri-apps/plugin-cli": ">=2.0.0-rc.1", + "@tauri-apps/plugin-clipboard-manager": ">=2.0.0-rc.1", + "@tauri-apps/plugin-dialog": ">=2.0.0-rc.1", + "@tauri-apps/plugin-notification": ">=2.0.0-rc.1", + "@tauri-apps/plugin-os": ">=2.0.0-rc.1", + "@tauri-apps/plugin-shell": "^2.0.0-rc", "autoprefixer": "^10.4.14", "d3": "^7.8.4", "data-urls": "^5.0.0", diff --git a/desktop/angular/src/app/integration/taur-app.ts b/desktop/angular/src/app/integration/taur-app.ts index 0e1d9e59f..ad663e6b0 100644 --- a/desktop/angular/src/app/integration/taur-app.ts +++ b/desktop/angular/src/app/integration/taur-app.ts @@ -3,7 +3,7 @@ import { writeText } from '@tauri-apps/plugin-clipboard-manager'; import { open } from '@tauri-apps/plugin-shell'; import { listen, once } from '@tauri-apps/api/event'; import { invoke } from '@tauri-apps/api/core' -import { getCurrent, Window } from '@tauri-apps/api/window'; +import { getCurrentWindow, Window } from '@tauri-apps/api/window'; // Returns a new uuidv4. If crypto.randomUUID is not available it fals back to // using Math.random(). While this is not as random as it should be it's still @@ -102,7 +102,7 @@ export class TauriIntegrationService implements IntegrationService { // we waste some system resources due to tauri window objects and the angular // application. - getCurrent().hide() + getCurrentWindow().hide() return Promise.resolve(); } @@ -164,7 +164,7 @@ export class TauriIntegrationService implements IntegrationService { } openApp() { - Window.getByLabel("splash")?.close(); + Window.getByLabel("splash").then(splash => { splash?.close();}); const current = Window.getCurrent() current.isVisible() @@ -177,7 +177,7 @@ export class TauriIntegrationService implements IntegrationService { } closePrompt() { - Window.getByLabel("prompt")?.close(); + Window.getByLabel("prompt").then(window => { window?.close();}); } openPrompt() { @@ -185,32 +185,34 @@ export class TauriIntegrationService implements IntegrationService { return; } - if (Window.getByLabel("prompt")) { - return; - } + Window.getByLabel("prompt").then(prompt => { + if (prompt) { + return; + } - const promptWindow = new Window("prompt", { - alwaysOnTop: true, - decorations: false, - minimizable: false, - maximizable: false, - resizable: false, - title: 'Portmaster Prompt', - visible: false, // the prompt marks it self as visible. - skipTaskbar: true, - closable: false, - center: true, - width: 600, - height: 300, - - // in src/main.ts we check the current location path - // and if it matches /prompt, we bootstrap the PromptEntryPointComponent - // instead of the AppComponent. - url: `http://${window.location.host}/prompt`, - } as any) - - promptWindow.once("tauri://error", (err) => { - console.error(err); + const promptWindow = new Window("prompt", { + alwaysOnTop: true, + decorations: false, + minimizable: false, + maximizable: false, + resizable: false, + title: 'Portmaster Prompt', + visible: false, // the prompt marks it self as visible. + skipTaskbar: true, + closable: false, + center: true, + width: 600, + height: 300, + + // in src/main.ts we check the current location path + // and if it matches /prompt, we bootstrap the PromptEntryPointComponent + // instead of the AppComponent. + url: `http://${window.location.host}/prompt`, + } as any) + + promptWindow.once("tauri://error", (err) => { + console.error(err); + }); }); } } diff --git a/desktop/angular/src/app/prompt-entrypoint/prompt-entrypoint.ts b/desktop/angular/src/app/prompt-entrypoint/prompt-entrypoint.ts index 23bf9f01f..f16d3f557 100644 --- a/desktop/angular/src/app/prompt-entrypoint/prompt-entrypoint.ts +++ b/desktop/angular/src/app/prompt-entrypoint/prompt-entrypoint.ts @@ -1,10 +1,10 @@ import { CommonModule } from "@angular/common"; import { Component, OnInit, TrackByFunction, inject } from "@angular/core"; import { AppProfile, AppProfileService, PortapiService } from "@safing/portmaster-api"; -import { combineLatest, combineLatestAll, forkJoin, map, merge, mergeAll, of, switchMap } from "rxjs"; +import { combineLatest, forkJoin, map, of, switchMap } from "rxjs"; import { ConnectionPrompt, NotificationType, NotificationsService } from "../services"; import { SfngAppIconModule } from "../shared/app-icon"; -import { getCurrent } from '@tauri-apps/api/window'; +import { getCurrentWindow } from '@tauri-apps/api/window'; import { CountryFlagModule } from "../shared/country-flag"; interface Prompt { @@ -64,7 +64,7 @@ export class PromptEntryPointComponent implements OnInit { // show the prompt now since we're ready if (this.prompts.length) { - getCurrent()!.show(); + getCurrentWindow()!.show(); } }) } diff --git a/desktop/tauri/src-tauri/Cargo.lock b/desktop/tauri/src-tauri/Cargo.lock index d7efb5ec0..8d9389859 100644 --- a/desktop/tauri/src-tauri/Cargo.lock +++ b/desktop/tauri/src-tauri/Cargo.lock @@ -235,7 +235,7 @@ dependencies = [ "open", "reqwest", "rfd", - "rust-ini 0.20.0", + "rust-ini", "serde", "serde_json", "sha", @@ -335,6 +335,24 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "ashpd" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01992ad7774250d5b7fe214e2676cb99bf92564436d8135ab44fe815e71769a9" +dependencies = [ + "async-fs 2.1.2", + "async-net", + "enumflags2", + "futures-channel", + "futures-util", + "rand 0.8.5", + "serde", + "serde_repr", + "url", + "zbus 3.15.2", +] + [[package]] name = "ashpd" version = "0.8.1" @@ -349,7 +367,7 @@ dependencies = [ "serde_repr", "tokio", "url", - "zbus", + "zbus 4.4.0", ] [[package]] @@ -364,13 +382,23 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-broadcast" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener 2.5.3", + "futures-core", +] + [[package]] name = "async-broadcast" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" dependencies = [ - "event-listener", + "event-listener 5.3.1", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -396,20 +424,52 @@ checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" dependencies = [ "async-task", "concurrent-queue", - "fastrand", - "futures-lite", + "fastrand 2.1.0", + "futures-lite 2.3.0", "slab", ] +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "blocking", + "futures-lite 1.13.0", +] + [[package]] name = "async-fs" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ - "async-lock", + "async-lock 3.4.0", "blocking", - "futures-lite", + "futures-lite 2.3.0", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", ] [[package]] @@ -418,30 +478,67 @@ version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" dependencies = [ - "async-lock", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite", + "futures-lite 2.3.0", "parking", - "polling", + "polling 3.7.3", "rustix 0.38.34", "slab", "tracing", "windows-sys 0.59.0", ] +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + [[package]] name = "async-lock" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener", + "event-listener 5.3.1", "event-listener-strategy", "pin-project-lite", ] +[[package]] +name = "async-net" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io 2.3.4", + "blocking", + "futures-lite 2.3.0", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.34", + "windows-sys 0.48.0", +] + [[package]] name = "async-process" version = "2.2.4" @@ -449,14 +546,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8a07789659a4d385b79b18b9127fc27e1a59e1e89117c78c5ea3b806f016374" dependencies = [ "async-channel", - "async-io", - "async-lock", + "async-io 2.3.4", + "async-lock 3.4.0", "async-signal", "async-task", "blocking", "cfg-if", - "event-listener", - "futures-lite", + "event-listener 5.3.1", + "futures-lite 2.3.0", "rustix 0.38.34", "tracing", "windows-sys 0.59.0", @@ -479,8 +576,8 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "async-io", - "async-lock", + "async-io 2.3.4", + "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", @@ -824,7 +921,7 @@ dependencies = [ "async-channel", "async-task", "futures-io", - "futures-lite", + "futures-lite 2.3.0", "piper", ] @@ -1089,12 +1186,12 @@ dependencies = [ [[package]] name = "cargo-mobile2" -version = "0.13.2" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebaedf7b7e292b7f41f892f5c96ee15544e21814e89d0b6b8dc06740a69dabe5" +checksum = "d0b8132519bea2d46174e777bd36d480d93afbe1df31c27cacfb411ff152bba1" dependencies = [ "colored", - "core-foundation 0.9.4", + "core-foundation 0.10.0", "deunicode", "duct", "dunce", @@ -1119,7 +1216,7 @@ dependencies = [ "toml 0.8.19", "ureq", "which", - "windows 0.57.0", + "windows 0.58.0", "x509-certificate", ] @@ -1748,7 +1845,7 @@ version = "3.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" dependencies = [ - "nix", + "nix 0.29.0", "windows-sys 0.59.0", ] @@ -1782,17 +1879,19 @@ dependencies = [ [[package]] name = "dark-light" version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a76fa97167fa740dcdbfe18e8895601e1bc36525f09b044e00916e717c03a3c" +source = "git+https://github.com/vlabo/rust-dark-light?rev=1f955c84d0ea05729bb5ecab29fb1b315b9897de#1f955c84d0ea05729bb5ecab29fb1b315b9897de" dependencies = [ + "anyhow", + "ashpd 0.7.0", "dconf_rs", "detect-desktop-environment", - "dirs 4.0.0", + "futures", "objc", - "rust-ini 0.18.0", + "rust-ini", "web-sys", - "winreg 0.10.1", - "zbus", + "winreg", + "xdg", + "zbus 3.15.2", ] [[package]] @@ -1941,6 +2040,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -2007,9 +2117,9 @@ dependencies = [ [[package]] name = "detect-desktop-environment" -version = "0.2.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21d8ad60dd5b13a4ee6bd8fa2d5d88965c597c67bce32b5fc49c94f55cb50810" +checksum = "cf27a1bbe31ac901a2350a6316b1f7056067118abe6bf1ff015d5950ac5e3eb3" [[package]] name = "deunicode" @@ -2053,22 +2163,13 @@ dependencies = [ "winapi", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys 0.3.7", -] - [[package]] name = "dirs" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ - "dirs-sys 0.4.1", + "dirs-sys", ] [[package]] @@ -2081,17 +2182,6 @@ dependencies = [ "dirs-sys-next", ] -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users 0.4.5", - "winapi", -] - [[package]] name = "dirs-sys" version = "0.4.1" @@ -2155,12 +2245,6 @@ dependencies = [ "syn 2.0.75", ] -[[package]] -name = "dlv-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - [[package]] name = "dlv-list" version = "0.5.2" @@ -2329,7 +2413,7 @@ dependencies = [ "rustc_version", "toml 0.8.19", "vswhom", - "winreg 0.52.0", + "winreg", ] [[package]] @@ -2463,6 +2547,23 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + [[package]] name = "event-listener" version = "5.3.1" @@ -2480,7 +2581,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener", + "event-listener 5.3.1", "pin-project-lite", ] @@ -2511,6 +2612,15 @@ dependencies = [ "regex-syntax 0.8.4", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.1.0" @@ -2557,7 +2667,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" dependencies = [ - "memoffset", + "memoffset 0.9.1", "rustc_version", ] @@ -2740,6 +2850,7 @@ checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", + "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -2779,13 +2890,28 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-lite" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand", + "fastrand 2.1.0", "futures-core", "futures-io", "parking", @@ -3464,7 +3590,7 @@ dependencies = [ "http-body", "hyper", "pin-project-lite", - "socket2", + "socket2 0.5.7", "tokio", "tower", "tower-service", @@ -4430,6 +4556,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -4618,6 +4753,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", +] + [[package]] name = "nix" version = "0.29.0" @@ -4628,7 +4775,7 @@ dependencies = [ "cfg-if", "cfg_aliases", "libc", - "memoffset", + "memoffset 0.9.1", ] [[package]] @@ -4699,7 +4846,7 @@ dependencies = [ "mac-notification-sys", "serde", "tauri-winrt-notification 0.2.1", - "zbus", + "zbus 4.4.0", ] [[package]] @@ -5109,23 +5256,13 @@ dependencies = [ "num-traits", ] -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list 0.3.0", - "hashbrown 0.12.3", -] - [[package]] name = "ordered-multimap" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" dependencies = [ - "dlv-list 0.5.2", + "dlv-list", "hashbrown 0.14.5", ] @@ -5725,7 +5862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand", + "fastrand 2.1.0", "futures-io", ] @@ -5782,6 +5919,22 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "polling" version = "3.7.3" @@ -6282,7 +6435,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "winreg 0.52.0", + "winreg", ] [[package]] @@ -6318,7 +6471,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251" dependencies = [ - "ashpd", + "ashpd 0.8.1", "block", "dispatch", "glib-sys", @@ -6493,16 +6646,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap 0.4.3", -] - [[package]] name = "rust-ini" version = "0.20.0" @@ -6510,7 +6653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a" dependencies = [ "cfg-if", - "ordered-multimap 0.7.3", + "ordered-multimap", ] [[package]] @@ -7173,6 +7316,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "socket2" version = "0.5.7" @@ -7466,9 +7619,9 @@ dependencies = [ [[package]] name = "swift-rs" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bbdb58577b6301f8d17ae2561f32002a5bae056d444e0f69e611e504a276204" +checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" dependencies = [ "base64 0.21.7", "serde", @@ -7579,9 +7732,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.29.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6775bcf3c1da33f848ede9cff5883ed1e45a29f66533ce42ad06c93ae514ed59" +checksum = "d3a97abbc7d6cfd0720da3e06fcb1cf2ac87cbfdb5bbbce103a1279a211c4d81" dependencies = [ "bitflags 2.6.0", "cocoa 0.26.0", @@ -7652,9 +7805,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.0.0-rc.3" +version = "2.0.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79776954e2cd6b6c3b56e2cd99905a3a166017495a39ac8eb4c85dd8ea8704b4" +checksum = "e8345ccc676ef16e26b61fc0f5340b4e770678b1e1f53f08c69ebdac5e56b422" dependencies = [ "anyhow", "bytes", @@ -7688,7 +7841,7 @@ dependencies = [ "tauri-macros", "tauri-runtime", "tauri-runtime-wry", - "tauri-utils 2.0.0-rc.3", + "tauri-utils 2.0.0-rc.7", "thiserror", "tokio", "tray-icon", @@ -7702,9 +7855,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.0.0-rc.3" +version = "2.0.0-rc.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc103bde77870e08d5fc8765615b9615997827550b626fbc4ebbd7a1fbfe2a2" +checksum = "7d5ad5fcfaf02cf79aa6727f6c5df38567d8dce172b00b62690c6bc46c08b7ce" dependencies = [ "anyhow", "cargo_toml", @@ -7716,7 +7869,7 @@ dependencies = [ "semver", "serde", "serde_json", - "tauri-utils 2.0.0-rc.3", + "tauri-utils 2.0.0-rc.7", "tauri-winres", "toml 0.8.19", "walkdir", @@ -7724,9 +7877,9 @@ dependencies = [ [[package]] name = "tauri-bundler" -version = "2.0.1-rc.2" +version = "2.0.1-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45d29230559aed6c972799165ba0eab8c99ed5af7d5ae91649d16bd589246" +checksum = "00a0e120d67416e774923fc07a7b531ba6898ed08f0d6e07fe79d7e3da7e0c04" dependencies = [ "anyhow", "ar", @@ -7754,7 +7907,7 @@ dependencies = [ "tar", "tauri-icns", "tauri-macos-sign", - "tauri-utils 2.0.0-rc.3", + "tauri-utils 2.0.0-rc.7", "tempfile", "thiserror", "time", @@ -7768,9 +7921,9 @@ dependencies = [ [[package]] name = "tauri-cli" -version = "2.0.0-rc.4" +version = "2.0.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390d66d643b86de471b9c38b409357096f626ff2425cb02a9ff9f77eed1ecf32" +checksum = "ddc42d318b25224c40f88550308f8cc8746a38534d450ce9c553f8c93f335499" dependencies = [ "anyhow", "axum", @@ -7830,7 +7983,8 @@ dependencies = [ "tauri-icns", "tauri-macos-sign", "tauri-utils 1.6.0", - "tauri-utils 2.0.0-rc.3", + "tauri-utils 2.0.0-rc.7", + "tempfile", "tokio", "toml 0.8.19", "toml_edit 0.22.20", @@ -7842,9 +7996,9 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.0.0-rc.3" +version = "2.0.0-rc.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea061e6be9b37ab455eadc189f45617deafc85c94f78f9cd584862a6deaa83d1" +checksum = "809ef6316726fc72593d296cf6f4e7461326e310c313d6a6c42b6e7f1e2671cf" dependencies = [ "base64 0.22.1", "brotli", @@ -7859,7 +8013,7 @@ dependencies = [ "serde_json", "sha2", "syn 2.0.75", - "tauri-utils 2.0.0-rc.3", + "tauri-utils 2.0.0-rc.7", "thiserror", "time", "url", @@ -7898,16 +8052,16 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.0.0-rc.3" +version = "2.0.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e20d6f6f96f55a43339c465b3c8205d71940372d54d7c665c5329e8e4ba35d0" +checksum = "1359e8861d210d25731f8b1bfbb4d111dd06406cf73c59659366ef450364d811" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.75", "tauri-codegen", - "tauri-utils 2.0.0-rc.3", + "tauri-utils 2.0.0-rc.7", ] [[package]] @@ -7922,7 +8076,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "tauri-utils 2.0.0-rc.3", + "tauri-utils 2.0.0-rc.7", "toml 0.8.19", "walkdir", ] @@ -8072,7 +8226,7 @@ dependencies = [ "tauri", "thiserror", "windows-sys 0.52.0", - "zbus", + "zbus 4.4.0", ] [[package]] @@ -8092,9 +8246,9 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.0.0-rc.3" +version = "2.0.0-rc.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e736d3293f8347e5d2c5b250fe0e5b873499f5483578b139445dbbf802e2e5" +checksum = "75c72b844f387bfc3341c355f3e16b8cbf4161848fa4e348670effb222cd3ba5" dependencies = [ "dpi", "gtk", @@ -8103,7 +8257,7 @@ dependencies = [ "raw-window-handle", "serde", "serde_json", - "tauri-utils 2.0.0-rc.3", + "tauri-utils 2.0.0-rc.7", "thiserror", "url", "windows 0.58.0", @@ -8111,9 +8265,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.0.0-rc.3" +version = "2.0.0-rc.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fead81c1bd0205d5f02580e64f522704618274e784c2d1c127e4ba19acd0b79" +checksum = "73accf936a7cd01d1382de7850726fdf6c1f6ab3b01ccb7a0950cb852e332596" dependencies = [ "cocoa 0.26.0", "gtk", @@ -8125,7 +8279,7 @@ dependencies = [ "softbuffer", "tao", "tauri-runtime", - "tauri-utils 2.0.0-rc.3", + "tauri-utils 2.0.0-rc.7", "url", "webkit2gtk", "webview2-com", @@ -8166,9 +8320,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.0.0-rc.3" +version = "2.0.0-rc.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "285af18e09665ea15fdda04cb28fb579a4d71b4e1640628489fecca98838ca9a" +checksum = "d53d9fe87e985b273696ae22ce2b9f099a8f1b44bc8fb127467bda5fcb3e4371" dependencies = [ "aes-gcm", "brotli", @@ -8242,7 +8396,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", - "fastrand", + "fastrand 2.1.0", "once_cell", "rustix 0.38.34", "windows-sys 0.59.0", @@ -8432,7 +8586,7 @@ dependencies = [ "mio 1.0.2", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.7", "tokio-macros", "tracing", "windows-sys 0.52.0", @@ -8713,9 +8867,9 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b92252d649d771105448969f2b2dda4342ba48b77731b60d37c93665e26615b" +checksum = "131a65b2cef2081bc14dbcd414c906edbfa3bb5323dd7e748cc298614681196b" dependencies = [ "core-graphics 0.24.0", "crossbeam-channel", @@ -8799,7 +8953,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "memoffset", + "memoffset 0.9.1", "tempfile", "winapi", ] @@ -9145,6 +9299,12 @@ dependencies = [ "libc", ] +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + [[package]] name = "walkdir" version = "2.5.0" @@ -9452,16 +9612,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" -dependencies = [ - "windows-core 0.57.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows" version = "0.58.0" @@ -9503,18 +9653,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-core" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" -dependencies = [ - "windows-implement 0.57.0", - "windows-interface 0.57.0", - "windows-result 0.1.2", - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" version = "0.58.0" @@ -9539,17 +9677,6 @@ dependencies = [ "syn 2.0.75", ] -[[package]] -name = "windows-implement" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.75", -] - [[package]] name = "windows-implement" version = "0.58.0" @@ -9572,17 +9699,6 @@ dependencies = [ "syn 2.0.75", ] -[[package]] -name = "windows-interface" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.75", -] - [[package]] name = "windows-interface" version = "0.58.0" @@ -9885,15 +10001,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "winreg" version = "0.52.0" @@ -10039,6 +10146,12 @@ dependencies = [ "rustix 0.38.34", ] +[[package]] +name = "xdg" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" + [[package]] name = "xdg-home" version = "1.3.0" @@ -10064,29 +10177,70 @@ dependencies = [ "lzma-sys", ] +[[package]] +name = "zbus" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" +dependencies = [ + "async-broadcast 0.5.1", + "async-executor", + "async-fs 1.6.0", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process 1.8.1", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "byteorder", + "derivative", + "enumflags2", + "event-listener 2.5.3", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix 0.26.4", + "once_cell", + "ordered-stream", + "rand 0.8.5", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "xdg-home", + "zbus_macros 3.15.2", + "zbus_names 2.6.1", + "zvariant 3.15.2", +] + [[package]] name = "zbus" version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" dependencies = [ - "async-broadcast", + "async-broadcast 0.7.1", "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-process", + "async-fs 2.1.2", + "async-io 2.3.4", + "async-lock 3.4.0", + "async-process 2.2.4", "async-recursion", "async-task", "async-trait", "blocking", "enumflags2", - "event-listener", + "event-listener 5.3.1", "futures-core", "futures-sink", "futures-util", "hex", - "nix", + "nix 0.29.0", "ordered-stream", "rand 0.8.5", "serde", @@ -10098,9 +10252,23 @@ dependencies = [ "uds_windows", "windows-sys 0.52.0", "xdg-home", - "zbus_macros", - "zbus_names", - "zvariant", + "zbus_macros 4.4.0", + "zbus_names 3.0.0", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus_macros" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "zvariant_utils 1.0.1", ] [[package]] @@ -10113,7 +10281,18 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.75", - "zvariant_utils", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zbus_names" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" +dependencies = [ + "serde", + "static_assertions", + "zvariant 3.15.2", ] [[package]] @@ -10124,7 +10303,7 @@ checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" dependencies = [ "serde", "static_assertions", - "zvariant", + "zvariant 4.2.0", ] [[package]] @@ -10251,6 +10430,21 @@ dependencies = [ "zune-core", ] +[[package]] +name = "zvariant" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "url", + "zvariant_derive 3.15.2", +] + [[package]] name = "zvariant" version = "4.2.0" @@ -10262,7 +10456,20 @@ dependencies = [ "serde", "static_assertions", "url", - "zvariant_derive", + "zvariant_derive 4.2.0", +] + +[[package]] +name = "zvariant_derive" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils 1.0.1", ] [[package]] @@ -10275,7 +10482,18 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.75", - "zvariant_utils", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zvariant_utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] diff --git a/desktop/tauri/src-tauri/Cargo.toml b/desktop/tauri/src-tauri/Cargo.toml index beb9d5da7..db19639b6 100644 --- a/desktop/tauri/src-tauri/Cargo.toml +++ b/desktop/tauri/src-tauri/Cargo.toml @@ -12,11 +12,11 @@ rust-version = "1.60" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] -tauri-build = { version = "2.0.0-rc.3", features = [] } +tauri-build = { version = "2.0.0-rc.7", features = [] } [dependencies] # Tauri -tauri = { version = "2.0.0-rc.3", features = ["tray-icon", "image-png", "config-json5", "devtools"] } +tauri = { version = "2.0.0-rc.8", features = ["tray-icon", "image-png", "config-json5", "devtools"] } tauri-plugin-shell = "2.0.0-rc" tauri-plugin-dialog = "2.0.0-rc" tauri-plugin-clipboard-manager = "2.0.0-rc" @@ -26,7 +26,7 @@ tauri-plugin-notification = "2.0.0-rc" tauri-plugin-log = "2.0.0-rc" tauri-plugin-window-state = "2.0.0-rc" -tauri-cli = "2.0.0-rc.4" +tauri-cli = "2.0.0-rc.8" clap = { version = "4" } # General @@ -53,7 +53,7 @@ reqwest = { version = "0.12" } rfd = { version = "*", default-features = false, features = [ "tokio", "gtk3", "common-controls-v6" ] } open = "5.1.3" -dark-light = "1.1.1" +dark-light = { git = "https://github.com/vlabo/rust-dark-light", rev = "1f955c84d0ea05729bb5ecab29fb1b315b9897de" } # Linux only [target.'cfg(target_os = "linux")'.dependencies] diff --git a/desktop/tauri/src-tauri/capabilities/default.json b/desktop/tauri/src-tauri/capabilities/default.json index 18a426343..701c72280 100644 --- a/desktop/tauri/src-tauri/capabilities/default.json +++ b/desktop/tauri/src-tauri/capabilities/default.json @@ -22,6 +22,7 @@ "core:window:allow-is-visible", "core:window:allow-set-focus", "core:window:allow-close", + "core:window:allow-get-all-windows", "core:app:default", "core:image:default", "core:resources:default", diff --git a/desktop/tauri/src-tauri/gen/schemas/capabilities.json b/desktop/tauri/src-tauri/gen/schemas/capabilities.json index 66bbb674b..1a35eff17 100644 --- a/desktop/tauri/src-tauri/gen/schemas/capabilities.json +++ b/desktop/tauri/src-tauri/gen/schemas/capabilities.json @@ -1 +1 @@ -{"default":{"identifier":"default","description":"Capability for the main window","remote":{"urls":["http://localhost:817"]},"local":true,"windows":["main","splash"],"permissions":["core:path:default","core:event:allow-listen","core:event:allow-unlisten","core:event:allow-emit","core:event:allow-emit-to","core:window:allow-hide","core:window:allow-show","core:window:allow-is-visible","core:window:allow-set-focus","core:window:allow-close","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default","shell:allow-open","notification:default","window-state:allow-save-window-state","window-state:allow-restore-state","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text"]}} \ No newline at end of file +{"default":{"identifier":"default","description":"Capability for the main window","remote":{"urls":["http://localhost:817"]},"local":true,"windows":["main","splash"],"permissions":["core:path:default","core:event:allow-listen","core:event:allow-unlisten","core:event:allow-emit","core:event:allow-emit-to","core:window:allow-hide","core:window:allow-show","core:window:allow-is-visible","core:window:allow-set-focus","core:window:allow-close","core:window:allow-get-all-windows","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default","shell:allow-open","notification:default","window-state:allow-save-window-state","window-state:allow-restore-state","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text"]}} \ No newline at end of file diff --git a/desktop/tauri/src-tauri/src/config.rs b/desktop/tauri/src-tauri/src/config.rs new file mode 100644 index 000000000..600052950 --- /dev/null +++ b/desktop/tauri/src-tauri/src/config.rs @@ -0,0 +1,45 @@ +use std::fs; + +use log::{debug, error}; +use serde::{Deserialize, Serialize}; +use tauri::{AppHandle, Manager}; + +#[derive(Serialize, Deserialize)] +pub enum Theme { + Light, + Dark, + System, +} + +#[derive(Serialize, Deserialize)] +pub struct Config { + pub theme: Theme, +} + +const CONFIG_FILE_NAME: &'static str = "config.json"; + +pub fn save(app: &AppHandle, config: Config) -> tauri::Result<()> { + let config_dir = app.path().app_config_dir()?; + + let config_path = config_dir.join(CONFIG_FILE_NAME); + debug!("saving config file: {:?}", config_path); + let json = serde_json::to_string_pretty(&config)?; + fs::write(config_path, json)?; + Ok(()) +} + +pub fn load(app: &AppHandle) -> tauri::Result { + let config_dir = app.path().app_config_dir()?; + + let config_path = config_dir.join(CONFIG_FILE_NAME); + if let Ok(json) = fs::read_to_string(config_path) { + if let Ok(config) = serde_json::from_str(&json) { + return Ok(config); + } + } + + error!("failed to load config file returning default config"); + Ok(Config { + theme: Theme::System, + }) +} diff --git a/desktop/tauri/src-tauri/src/main.rs b/desktop/tauri/src-tauri/src/main.rs index a92f8a5e9..d269c4f39 100644 --- a/desktop/tauri/src-tauri/src/main.rs +++ b/desktop/tauri/src-tauri/src/main.rs @@ -14,6 +14,7 @@ mod service; mod xdg; // App modules +mod config; mod portmaster; mod traymenu; mod window; @@ -22,7 +23,7 @@ use log::{debug, error, info, LevelFilter}; use portmaster::PortmasterExt; use tauri_plugin_log::RotationStrategy; use traymenu::setup_tray_menu; -use window::{close_splash_window, create_main_window}; +use window::{close_splash_window, create_main_window, hide_splash_window}; #[macro_use] extern crate lazy_static; @@ -77,7 +78,11 @@ impl portmaster::Handler for WsHandler { // so we don't show the splash-screen when we loose connection. self.is_first_connect = false; - if let Err(err) = close_splash_window(&self.handle) { + // The order is important. If all current windows are destroyed tauri will exit. + // First create the main ui window then destroy the splash screen. + + // Hide splash screen. Will be closed after main window is created. + if let Err(err) = hide_splash_window(&self.handle) { error!("failed to close splash window: {}", err.to_string()); } @@ -90,6 +95,11 @@ impl portmaster::Handler for WsHandler { debug!("created main window") } + // Now it is safe to destroy the splash window. + if let Err(err) = close_splash_window(&self.handle) { + error!("failed to close splash window: {}", err.to_string()); + } + let handle = self.handle.clone(); tauri::async_runtime::spawn(async move { traymenu::tray_handler(cli, handle).await; diff --git a/desktop/tauri/src-tauri/src/traymenu.rs b/desktop/tauri/src-tauri/src/traymenu.rs index b3fef2baa..9d775475d 100644 --- a/desktop/tauri/src-tauri/src/traymenu.rs +++ b/desktop/tauri/src-tauri/src/traymenu.rs @@ -1,9 +1,11 @@ +use std::ops::Deref; use std::sync::atomic::AtomicBool; -use std::sync::Mutex; +use std::sync::{Mutex, RwLock}; use std::{collections::HashMap, sync::atomic::Ordering}; use log::{debug, error}; use tauri::tray::{MouseButton, MouseButtonState}; +use tauri::Manager; use tauri::{ image::Image, menu::{MenuBuilder, MenuItem, MenuItemBuilder, PredefinedMenuItem, SubmenuBuilder}, @@ -12,6 +14,7 @@ use tauri::{ }; use tauri_plugin_window_state::{AppHandleExt, StateFlags}; +use crate::config; use crate::{ portapi::{ client::PortAPI, @@ -32,6 +35,17 @@ pub type AppIcon = TrayIcon; static SPN_STATE: AtomicBool = AtomicBool::new(false); +#[derive(Copy, Clone)] +enum IconColor { + Red, + Green, + Blue, + Yellow, +} + +static CURRENT_ICON_COLOR: RwLock = RwLock::new(IconColor::Red); +pub static USER_THEME: RwLock = RwLock::new(dark_light::Mode::Default); + lazy_static! { static ref SPN_STATUS: Mutex>> = Mutex::new(None); static ref SPN_BUTTON: Mutex>> = Mutex::new(None); @@ -42,14 +56,20 @@ const PM_TRAY_ICON_ID: &'static str = "pm_icon"; // Icons +fn get_theme_mode() -> dark_light::Mode { + if let Ok(value) = USER_THEME.read() { + return *value.deref(); + } + return dark_light::detect(); +} + fn get_green_icon() -> &'static [u8] { const LIGHT_GREEN_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_light_green_64.png"); const DARK_GREEN_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_dark_green_64.png"); - let mode = dark_light::detect(); - match mode { + match get_theme_mode() { dark_light::Mode::Light => DARK_GREEN_ICON, _ => LIGHT_GREEN_ICON, } @@ -60,8 +80,7 @@ fn get_blue_icon() -> &'static [u8] { include_bytes!("../../../../assets/data/icons/pm_light_blue_64.png"); const DARK_BLUE_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_dark_blue_64.png"); - let mode = dark_light::detect(); - match mode { + match get_theme_mode() { dark_light::Mode::Light => DARK_BLUE_ICON, _ => LIGHT_BLUE_ICON, } @@ -72,8 +91,7 @@ fn get_red_icon() -> &'static [u8] { include_bytes!("../../../../assets/data/icons/pm_light_red_64.png"); const DARK_RED_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_dark_red_64.png"); - let mode = dark_light::detect(); - match mode { + match get_theme_mode() { dark_light::Mode::Light => DARK_RED_ICON, _ => LIGHT_RED_ICON, } @@ -82,20 +100,28 @@ fn get_red_icon() -> &'static [u8] { fn get_yellow_icon() -> &'static [u8] { const LIGHT_YELLOW_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_light_yellow_64.png"); - const DARK_YELLOW_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_dark_yellow_64.png"); - let mode = dark_light::detect(); - match mode { + match get_theme_mode() { dark_light::Mode::Light => DARK_YELLOW_ICON, _ => LIGHT_YELLOW_ICON, } } +fn get_icon(icon: IconColor) -> &'static [u8] { + match icon { + IconColor::Red => get_red_icon(), + IconColor::Green => get_green_icon(), + IconColor::Blue => get_blue_icon(), + IconColor::Yellow => get_yellow_icon(), + } +} + pub fn setup_tray_menu( app: &mut tauri::App, ) -> core::result::Result> { // Tray menu + load_theme(app.handle()); let open_btn = MenuItemBuilder::with_id("open", "Open App").build(app)?; let exit_ui_btn = MenuItemBuilder::with_id("exit_ui", "Exit UI").build(app)?; let shutdown_btn = MenuItemBuilder::with_id("shutdown", "Shut Down Portmaster").build(app)?; @@ -118,6 +144,7 @@ pub fn setup_tray_menu( let mut button_ref = SPN_STATUS.lock()?; *button_ref = Some(spn_status.clone()); } + // Setup SPN button let spn = MenuItemBuilder::with_id("spn_toggle", "Enable SPN") .build(app) @@ -127,6 +154,19 @@ pub fn setup_tray_menu( *button_ref = Some(spn.clone()); } + let system_theme = MenuItemBuilder::with_id("system_theme", "System") + .build(app) + .unwrap(); + let light_theme = MenuItemBuilder::with_id("light_theme", "Light") + .build(app) + .unwrap(); + let dark_theme = MenuItemBuilder::with_id("dark_theme", "Dark") + .build(app) + .unwrap(); + let theme_menu = SubmenuBuilder::new(app, "Icon Theme") + .items(&[&system_theme, &light_theme, &dark_theme]) + .build()?; + let force_show_window = MenuItemBuilder::with_id("force-show", "Force Show UI").build(app)?; let reload_btn = MenuItemBuilder::with_id("reload", "Reload User Interface").build(app)?; let developer_menu = SubmenuBuilder::new(app, "Developer") @@ -142,6 +182,8 @@ pub fn setup_tray_menu( &spn_status, &spn, &PredefinedMenuItem::separator(app)?, + &theme_menu, + &PredefinedMenuItem::separator(app)?, &exit_ui_btn, &shutdown_btn, &developer_menu, @@ -197,6 +239,9 @@ pub fn setup_tray_menu( "shutdown" => { app.portmaster().trigger_shutdown(); } + "system_theme" => update_icon_theme(app, dark_light::Mode::Default), + "dark_theme" => update_icon_theme(app, dark_light::Mode::Dark), + "light_theme" => update_icon_theme(app, dark_light::Mode::Light), other => { error!("unknown menu event id: {}", other); } @@ -248,16 +293,15 @@ pub fn update_icon(icon: AppIcon, subsystems: HashMap, spn_st } } - let next_icon = match failure.0 { - subsystem::FAILURE_WARNING => get_yellow_icon(), - subsystem::FAILURE_ERROR => get_red_icon(), + let icon_color = match failure.0 { + subsystem::FAILURE_WARNING => IconColor::Yellow, + subsystem::FAILURE_ERROR => IconColor::Red, _ => match spn_status.as_str() { - "connected" | "connecting" => get_blue_icon(), - _ => get_green_icon(), + "connected" | "connecting" => IconColor::Blue, + _ => IconColor::Green, }, }; - - _ = icon.set_icon(Some(Image::from_bytes(next_icon).unwrap())); + update_icon_color(&icon, icon_color); } pub async fn tray_handler(cli: PortAPI, app: tauri::AppHandle) { @@ -333,7 +377,7 @@ pub async fn tray_handler(cli: PortAPI, app: tauri::AppHandle) { } }; - _ = icon.set_icon(Some(Image::from_bytes(get_blue_icon()).unwrap())); + update_icon_color(&icon, IconColor::Blue); let mut subsystems: HashMap = HashMap::new(); let mut spn_status: String = "".to_string(); @@ -439,19 +483,83 @@ pub async fn tray_handler(cli: PortAPI, app: tauri::AppHandle) { }; debug!("Shutdown request received: {:?}", msg); match msg { - Response::Ok(_, _) | Response::New(_, _) | Response::Update(_, _) => { + Response::Ok(msg, _) | Response::New(msg, _) | Response::Update(msg, _) => { if let Err(err) = app.save_window_state(StateFlags::SIZE | StateFlags::POSITION) { error!("failed to save window state: {}", err); } - app.exit(0)}, + debug!("shutting down: {}", msg); + app.exit(0) + }, _ => {}, } } } } - update_spn_ui_state(false); - _ = icon.set_icon(Some(Image::from_bytes(get_red_icon()).unwrap())); + update_icon_color(&icon, IconColor::Red); +} + +fn update_icon_color(icon: &AppIcon, new_color: IconColor) { + if let Ok(mut value) = CURRENT_ICON_COLOR.write() { + *value = new_color; + } + _ = icon.set_icon(Some(Image::from_bytes(get_icon(new_color)).unwrap())); +} + +fn update_icon_theme(app: &tauri::AppHandle, theme: dark_light::Mode) { + if let Ok(mut value) = USER_THEME.write() { + *value = theme; + } + let icon = match app.tray_by_id(PM_TRAY_ICON_ID) { + Some(icon) => icon, + None => { + error!("cancel theme update: missing try icon"); + return; + } + }; + if let Ok(value) = CURRENT_ICON_COLOR.read() { + _ = icon.set_icon(Some(Image::from_bytes(get_icon(*value)).unwrap())); + } + for (_, v) in app.webview_windows() { + super::window::set_window_icon(&v); + } + save_theme(app, theme); +} + +fn load_theme(app: &tauri::AppHandle) { + match config::load(app) { + Ok(config) => { + let theme = match config.theme { + config::Theme::Light => dark_light::Mode::Light, + config::Theme::Dark => dark_light::Mode::Dark, + config::Theme::System => dark_light::Mode::Default, + }; + + if let Ok(mut value) = USER_THEME.write() { + *value = theme; + } + } + Err(err) => error!("failed to load config file: {}", err), + } +} + +fn save_theme(app: &tauri::AppHandle, mode: dark_light::Mode) { + match config::load(app) { + Ok(mut config) => { + let theme = match mode { + dark_light::Mode::Dark => config::Theme::Dark, + dark_light::Mode::Light => config::Theme::Light, + dark_light::Mode::Default => config::Theme::System, + }; + config.theme = theme; + if let Err(err) = config::save(app, config) { + error!("failed to save config file: {}", err) + } else { + debug!("config updated"); + } + } + Err(err) => error!("failed to load config file: {}", err), + } } fn update_spn_ui_state(enabled: bool) { diff --git a/desktop/tauri/src-tauri/src/window.rs b/desktop/tauri/src-tauri/src/window.rs index 46ec2ef1e..b5e526a4c 100644 --- a/desktop/tauri/src-tauri/src/window.rs +++ b/desktop/tauri/src-tauri/src/window.rs @@ -4,7 +4,7 @@ use tauri::{ WebviewWindow, WebviewWindowBuilder, }; -use crate::portmaster::PortmasterExt; +use crate::{portmaster::PortmasterExt, traymenu}; const LIGHT_PM_ICON: &'static [u8] = include_bytes!("../../../../assets/data/icons/pm_light_512.png"); @@ -51,11 +51,7 @@ pub fn create_main_window(app: &AppHandle) -> Result { // If the window is not yet navigated to the Portmaster UI, do it now. may_navigate_to_ui(&mut window, false); - - let _ = match dark_light::detect() { - dark_light::Mode::Light => window.set_icon(Image::from_bytes(DARK_PM_ICON).unwrap()), - _ => window.set_icon(Image::from_bytes(LIGHT_PM_ICON).unwrap()), - }; + set_window_icon(&window); #[cfg(debug_assertions)] if let Ok(_) = std::env::var("TAURI_SHOW_IMMEDIATELY") { @@ -83,6 +79,7 @@ pub fn create_splash_window(app: &AppHandle) -> Result { .title("Portmaster") .inner_size(600.0, 250.0) .build()?; + set_window_icon(&window); let _ = window.request_user_attention(Some(UserAttentionType::Informational)); @@ -98,6 +95,30 @@ pub fn close_splash_window(app: &AppHandle) -> Result<()> { return Err(tauri::Error::WindowNotFound); } +pub fn hide_splash_window(app: &AppHandle) -> Result<()> { + if let Some(window) = app.get_webview_window("splash") { + return window.hide(); + } + return Err(tauri::Error::WindowNotFound); +} + +pub fn set_window_icon(window: &WebviewWindow) { + let mut mode = if let Ok(value) = traymenu::USER_THEME.read() { + *value + } else { + dark_light::Mode::Default + }; + + if mode == dark_light::Mode::Default { + mode = dark_light::detect(); + } + + let _ = match mode { + dark_light::Mode::Light => window.set_icon(Image::from_bytes(DARK_PM_ICON).unwrap()), + _ => window.set_icon(Image::from_bytes(LIGHT_PM_ICON).unwrap()), + }; +} + /// Opens a window for the tauri application. /// /// If the main window has already been created, it is instructed to @@ -117,6 +138,7 @@ pub fn open_window(app: &AppHandle) -> Result { app.portmaster().show_window(); let _ = win.show(); let _ = win.set_focus(); + set_window_icon(&win); Ok(win) } None => {