Commit Graph
61 Commits
Author SHA1 Message Date
Lucas Nogueira 46f7c878a0 chore: fmt 2026-10-09 15:08:52 -03:00
a8acd178bd feat(shell): add process group spawn option (fix #1332) (#3351)
* feat(shell): add process group spawn option (fix #1332)

Add a `processGroup` boolean option to the shell plugin's spawn command.
When enabled, the child process is spawned in its own process group (POSIX)
or job object (Windows) using the `process-wrap` crate, so that killing
the child also kills the entire process tree.

This fixes the issue where programs like PyInstaller wrappers spawn a
child process that gets orphaned when Tauri kills the parent.

* test(shell): add PyInstaller simulation tests for process group kill

Add end-to-end tests that reproduce the exact scenario from issue #1332:
a wrapper process (like PyInstaller's bootloader) spawns a grandchild.

- Without process_group: killing the wrapper orphans the grandchild
- With process_group: killing the wrapper also kills the grandchild

* refactor(shell): drop redundant cfg gates, trim process-wrap features

Address review feedback on #3351:

- Remove `#[cfg(any(unix, windows))]` gates on `ChildKind::ProcessGroup`,
  the kill/pid match arms, and the spawn block, plus the now-dead
  `#[cfg(not(any(unix, windows)))]` fallback. That cfg only excluded wasm,
  which this plugin never builds for.
- Set `default-features = false` on process-wrap and enable only the
  features actually used: std, process-group (unix), creation-flags and
  job-object (windows). Drops kill-on-drop, process-session, and tracing.

* fix(shell): enable process-wrap tracing feature, fix CI formatting and changefile

- Add `tracing` feature to process-wrap: with default-features = false its
  Windows job_object.rs calls `debug\!` unconditionally while the import is
  gated behind `#[cfg(feature = "tracing")]`, failing the Windows build with
  "cannot find macro `debug`".
- Reformat process/mod.rs assertions to satisfy `cargo fmt --check`.
- Reindent the process-wrap features array to 2 spaces for taplo.
- Use covector package keys (`shell` / `shell-js`) in the change file so the
  check-change-files and covector status jobs pass.

* refactor(shell): unify child handling on process-wrap, drop SharedChild

Collapse the ChildKind enum and the per-platform GroupChild types into a
single process-wrap-backed child. The command always spawns through
StdCommandWrap; the process_group flag is now just an optional wrapper
rather than a switch into a separate child type.

This drops the shared_child dependency and resolves two review notes:
the Unix path no longer hand-rolls killpg, and kill() now goes through
process-wrap's kill (start_kill + wait), which reaps the entire process
group instead of only signalling it.

A background thread polls try_wait to surface the exit status, since
process-wrap's wrappers only expose &mut self wait methods (the reason
SharedChild was used on Unix in the first place).

* chore(example): add process group toggle to shell view

* fix(shell): pass typed creation flags to process-wrap on Windows

`process_wrap::std::CreationFlags` is a newtype over the `windows` crate's
`PROCESS_CREATION_FLAGS`, not a raw `u32`, so the Windows build failed to
compile. Depend on `windows` (already in the tree via `tauri`, pinned to the
same 0.61 that `process-wrap` links against) and use its `CREATE_NO_WINDOW`
constant, which drops the hand-rolled magic number.

The wrap is still required: `JobObject::pre_spawn` calls `creation_flags` and
would otherwise clobber the `CREATE_NO_WINDOW` set at construction.

* perf(shell): block on child exit instead of polling try_wait

The switch from `SharedChild` to `process-wrap` moved the child behind a
mutex, since `StdChildWrapper`'s wait methods take `&mut self` while both
the wait thread and `CommandChild::kill()` need access. A blocking wait
would hold the lock for the child's whole lifetime and starve `kill()`,
so the wait thread polled `try_wait` every 10ms instead.

Block on the raw process outside the lock using a wait that does not reap
(`waitid` with `WNOWAIT` on unix, `WaitForSingleObject` on windows), then
take the lock once to let process-wrap collect the exit status. This is
the same technique shared_child uses internally, applied on top of
process-wrap's kill/reap semantics. No new dependencies or Cargo features
are required.

`kill()` reaps the child while holding the lock, so the raw wait can lose
that race and return ECHILD. That means the exit status is already cached
in the wrapper, so it is treated as success and the status is collected
via `try_wait`. Without this guard, a stress test of 300 spawn+kill
cycles produced 36 Error events in place of Terminated; with it, none in
900 cycles. The `try_wait` loop stays as a defensive fallback, though in
practice the first call succeeds immediately.

Mean latency for `Command::output()` on macOS (debug, 30 iterations of
`echo`) drops from 13.22ms to ~1.8ms, and 10 idle 5s children cost ~11ms
CPU total instead of ~75ms with the poll loop.

* fix(shell): keep CREATE_NO_WINDOW on process-group children (windows)

process-wrap's CreationFlags/JobObject coordination is broken during
spawn (watchexec/process-wrap#35): JobObject::pre_spawn cannot see the
CreationFlags wrapper, so it overwrote our flags with just
CREATE_SUSPENDED and process-group children flashed a console window.

Register CreationFlags(CREATE_SUSPENDED | CREATE_NO_WINDOW) after
JobObject so its pre_spawn runs last and wins. CREATE_SUSPENDED is kept
so the child cannot spawn grandchildren before job assignment; the same
upstream bug keeps wrap_child's resume check from seeing it, so the
child is still resumed.

* test(shell): run the process-tree kill tests on windows

Add a powershell variant of the pyinstaller simulation script and lift
the unix-only gates on the process-group tests, so the windows job in
test-rust exercises the job-object spawn/kill path instead of skipping
it. Both pyinstaller tests now also assert that a Terminated event is
still delivered after kill().

* Update plugins/shell/src/process/mod.rs

Co-authored-by: Fabian-Lars <30730186+FabianLars@users.noreply.github.com>

* Update .changes/shell-process-group.md

Co-authored-by: Fabian-Lars <30730186+FabianLars@users.noreply.github.com>

* Update plugins/shell/src/process/mod.rs

Co-authored-by: Fabian-Lars <30730186+FabianLars@users.noreply.github.com>

* Delete .changes/shell-wait-no-poll.md

* refactor(shell): replace process-wrap with shared_child and an inlined job object

Use std process groups on unix and a job object on windows, with
shared_child handling wait and kill on all platforms.

* fix(shell): kill the process group even after its leader exited

CommandChild::kill returned early once the direct child had been reaped,
so killpg/TerminateJobObject never ran and anything the child left running
in its process group or job object survived, including on app exit.

Adds a launcher-style test (the child starts a grandchild and exits) that
runs on Windows, Linux and macOS.

* fix(shell): restore Debug on CommandChild

Dropping the derive was a breaking change for downstream types that derive
Debug and hold a CommandChild.

* fix(shell): don't block the main thread in the kill command

CommandChild::kill now waits for the child to exit, and the sync kill
command ran it on the main thread while still holding the children lock.
Make the command async and release the lock before killing.

---------

Co-authored-by: Fabian-Lars <30730186+FabianLars@users.noreply.github.com>
Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2026-10-09 15:08:15 -03:00
Lucas Fernandes Nogueira 65ce65bdbb fix(ci): Android e2e flakes, shell Terminated sent before output (#3672)
* fix(ci): Android e2e flakes, shell `Terminated` sent before output

- close "isn't responding" system dialogs before each spec and hide error dialogs on the CI emulator:
  a launcher ANR dialog takes input focus from the app, and Android then denies clipboard reads
- retry switching to the webview context until it succeeds instead of running the spec in the
  native context when the first switch fails with "No such context found"
- save the focused window, a screenshot and logcat when an Android test fails
- shell: wait for the pipe readers to finish before emitting `Terminated`; the readers took their
  read lock on their own thread, so a child exiting quickly could have `close` emitted before
  its output

* Apply suggestion from @lucasfernog
2026-10-07 13:51:35 -03:00
Lucas Nogueira a433ec09d1 fix: mobile clippy warnings 2026-09-26 15:57:33 -03:00
Lucas Nogueira 3d8a3c877b chore: edition 2024 2026-09-26 15:36:22 -03:00
Lucas Nogueira a87a3c7d44 chore: update documentation 2026-09-22 11:30:47 -03:00
Tony 13c63af965 chore: fix clippy (#3488) 2026-07-15 16:01:07 +08:00
renovate[bot]andTony 2c0883e64e chore(deps): update dependency vite to v8 (#3346)
* chore(deps): update dependency vite to v8

* `pnpm update --recursive`

* Regenerate api-iife

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tony <legendmastertony@gmail.com>
2026-03-20 20:05:30 +08:00
Ale Sanchez d4613ff002 fix(shell): Make sidecars work in tests (fix #13767) (#3234) 2026-01-26 17:12:42 +01:00
TungliesandTony 31415effdf docs(shell): update example to include Encoding usage in Command::spawn (#3183)
* docs(shell): update example to include Encoding usage in `Command::spawn`

* docs(shell): update patch level to minor for Encoding usage in `Command::spawn` documentation

* Update .changes/doc-to-Encoding-usage-in-shell.md

Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>

* docs(shell): update examples to demonstrate manual Encoding usage in command output

* Update plugins/shell/src/process/mod.rs

Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>

* docs(shell): update example to use 'windows-1252' encoding in command output

* Update plugins/shell/src/process/mod.rs

Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>

* docs(shell): update example command in documentation to use 'some-program' with 'some-arg'

* Bump shell-js in change file

* Fix indent
2025-12-29 10:58:55 +08:00
Nazar AntoniukandFabian-Lars a4aa53ab90 chore(shell): clarify that the code field in ExitStatus is intentionally left private (#3116)
Co-authored-by: Fabian-Lars <github@fabianlars.de>
2025-11-20 15:33:19 +01:00
Fabian-Lars 5438a5cd22 chore: apply clippy fixes (#3092) 2025-11-09 18:43:17 +01:00
Lucas Fernandes Nogueira d865ed4768 fix(shell): run sidecar with dots in filename, closes #2310 (#2950)
* fix(shell): run sidecar with dots in filename, closes #2310

* fix import

* remove dead code

* code review suggestions

* clippy

* clippy
2025-08-25 10:44:47 -03:00
Lucas Fernandes NogueiraandTony 50cebdb6d5 chore(deps): update to tauri 2.8.0 (#2925)
* chore(deps): update to tauri 2.8.0

* fmt

* uipdate build

* tauri 2.8.1 and bump toml in plugin-fs

* tauri 2.8.1

* 2.8.2

* clippy [skip ci]

---------

Co-authored-by: Tony <legendmastertony@gmail.com>
2025-08-19 10:09:44 -03:00
9629c2f4f9 [v2][log]: Add generic fern::Dispatch TargetKind to log (#2600)
* [v2][log]: Add generic fern::Dispatch TargetKind to log

Original: https://github.com/tauri-apps/plugins-workspace/pull/1130/commits/b691382d1ea54733ca837995cfac9f82ea05f168

* Add change file

* clippy

---------

Co-authored-by: Tony <legendmastertony@gmail.com>
Co-authored-by: venkr <venkateshrameshkumar+1@gmail.com>
2025-04-07 10:13:17 +08:00
9cf0390a52 Merge commit from fork
* fix(shell): properly validate open scope

* change empty regex to an impossible match

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
Co-authored-by: Chip Reed <chip@chip.sh>
2025-04-02 00:24:25 -03:00
renovate[bot]andFabianLars 71f95c9f05 chore(deps): update rust crate windows to 0.60 (v2) (#2445)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: FabianLars <github@fabianlars.de>
2025-02-27 11:45:55 +01:00
enri90andFabianLars 05c62d731f feat(upload): Added body to download function (#1523)
Co-authored-by: FabianLars <fabianlars@fabianlars.de>
2024-12-03 14:35:11 +01:00
Amr Bashir 383e636a8e feat: add tauri-plugin-opener (#2019) 2024-11-20 00:50:02 +02:00
Fabian-Lars 51856e9e0a docs: Remove header image from inline docs (#2045) 2024-11-13 16:07:29 +01:00
Amr Bashir 51ddf6a715 fix(shell): use async command for open JS API (#1881)
closes tauri-apps/tauri#11212
2024-10-09 08:47:25 -03:00
Amr BashirandLucas Nogueira 44273b9889 fix(shell): fix schema requiring sidecar property even though it is optional (#1839)
* fix(shell): fix schema requiring `sidecar` property even though it is optional

* fix clippy

* make `cmd` and `sidecar` exclusive

* make args optional

* cleanup

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2024-10-01 10:16:14 -03:00
Lucas Fernandes Nogueira cc03ccf5e0 fix(fs): app scopes not properly enabling paths (#1774) 2024-09-13 09:57:46 -03:00
Lucas Fernandes Nogueira 72c2ce82c1 chore(deep-link): fix example, update documentation (#1725)
* chore(deep-link): fix example, update documentation

* update lock file

* fix lint, add header

* fmt
2024-09-04 08:37:34 -03:00
Lucas Fernandes Nogueira 34df132fb1 feat(shell): enhance regex validators to match on entire string (#1603) 2024-08-02 10:03:35 -03:00
Lucas Fernandes Nogueira 22a17980ff feat: update to tauri beta.24 (#1537)
* feat: update to tauri beta.24

* remove .tauri

* pnpm build
2024-07-12 17:59:17 -03:00
Amr Bashir aff47992b3 fix(shell): make execute command async (#1362)
closes #1361
2024-05-23 02:16:39 +03:00
Amr Bashir cb0a788d17 fix(shell): use serde untagged not flatten (#1328) 2024-05-21 20:10:36 +03:00
Tony e1d06b93b7 refactor: drop eslint config love (#1341)
* Drop eslint config love

* More eqeqeq

* Even more
2024-05-18 11:00:09 +02:00
Amr Bashirandfabianlars f0fb25a9b7 feat(shell): support opening URLs on mobile (#1319)
* feat(shell): support opening URLs on mobile

closes #595

* Update and rename StorePlugin.swift to ShellPlugin.swift

* unwrap

* fix func name (ios)

* use undeprecated func if avail

---------

Co-authored-by: fabianlars <fabianlars@fabianlars.de>
2024-05-16 02:09:52 +03:00
Amr Bashir eb1679b997 fix(core/shell): speedup Command.execute & fix extra new lines (#1299)
* fix(core/shell): speedup `Command.execute` & fix extra new lines

The speed gains comes from running the Command in Rust fully and returning the result in one go instead of using events.

The extra new lines was a regression from https://github.com/tauri-apps/tauri/pull/6519
ref: https://github.com/tauri-apps/tauri/issues/7684#issuecomment-2100897383

* fmt

* dedup code
2024-05-09 18:15:03 +03:00
Amr Bashir 5c1b7917e4 fix(shell/command): retry sending events when it fails (#1298)
ref: https://github.com/tauri-apps/tauri/issues/7684
2024-05-09 10:38:56 -03:00
Graham Held b4efa58d5d feat(shell) raw-encoded pipe reader directly outputs buffer (no newline scan) (#1231)
* Shell raw-encoded pipe reader directly outputs buffer (no newline scan)

* Suggestions from code review and add .changes file

* fmt
2024-05-02 16:00:03 +03:00
renovate[bot]andFabianLars faa89850d0 chore(deps): replace dependency eslint-config-standard-with-typescript with eslint-config-love 43.1.0 (#1228)
* chore(deps): replace dependency eslint-config-standard-with-typescript with eslint-config-love 43.1.0

* actually apply the rules lol

* rebuild

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: FabianLars <fabianlars@fabianlars.de>
2024-04-23 00:40:51 +02:00
Lucas Fernandes Nogueira a04ea2f382 refactor: only inject API IIFE script when withGlobalTauri is true (#1071)
* refactor: only inject API IIFE script when withGlobalTauri is true

* fmt

* update tauri
2024-03-19 15:03:20 -03:00
Jason Tsai 040004a6b9 chore(shell): change schema property name command to cmd (#1069)
* chore: fix shell plugin `command` property in schema

* chore: add changelog
2024-03-12 15:20:56 +02:00
Lucas Fernandes Nogueira cacf544d51 chore(deps): update to tauri beta.9 (#1037) 2024-03-07 00:08:52 -03:00
Lucas Nogueira 8461cf1d1b chore: update to tauri beta.3 2024-02-19 17:10:49 -03:00
Amr Bashir e856adc72c fix(shell): export open module (#939)
closes #934
2024-02-16 16:27:19 +01:00
d198c01486 feat: update to tauri beta, add permissions (#862)
Co-authored-by: Lucas Nogueira <lucas@tauri.app>
Co-authored-by: Lucas Nogueira <lucas@crabnebula.dev>
2024-02-03 15:14:41 -03:00
Lucas Fernandes Nogueira 15dc7060e8 fix(shell): deadlock on read line error (#923) 2024-02-01 00:01:23 -03:00
Amr BashirandLucas Nogueira 1b98b85a1f refactor: simplify rollup config and match @tauri-apps/api output style (#722)
* refactor: simplify rollup config and match `@tauri-apps/api` output style

* add license headers

* update api-iife.js [skip ci]

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2023-11-14 21:09:53 +02:00
Lucas Fernandes NogueiraandAmr Bashir e438e0a62d feat: update to alpha.17, typed mobile plugin IPC arguments (#676)
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
2023-10-29 16:06:44 -03:00
MoandLucas Nogueira beb6b139eb Fix invoke calls in dialog & shell init scripts (#675)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
2023-10-22 10:09:40 -03:00
Lucas Fernandes NogueiraandAmr Bashir 5c137365c6 chore: update to tauri alpha.16, api alpha.9 (#673)
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
2023-10-20 13:50:18 -03:00
Lucas Fernandes Nogueira 265dbc02e3 chore(shell): remove outdated todo (#559) 2023-08-14 15:54:17 -07:00
Lucas Fernandes Nogueira d74fc0a097 feat: update to alpha.11 (#555) 2023-08-14 14:51:20 -03:00
Lucas Fernandes NogueiraandAmr Bashir 5b3210c224 feat(shell): expand Command APIs (#526)
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
2023-08-07 09:38:12 -03:00
Fabian-Lars aba07c27b8 Merge v1 into v2 (#468)
Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: FabianLars <fabianlars@fabianlars.de>
Co-authored-by: FabianLars <FabianLars@users.noreply.github.com>
Co-authored-by: Alexandre Dang <124160233+vdang-crabnebula@users.noreply.github.com>
Co-authored-by: Ludea <ludovicw35@hotmail.com>
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
Co-authored-by: Duke Jones <104690+dukejones@users.noreply.github.com>
Co-authored-by: NaokiM03 <37442712+NaokiM03@users.noreply.github.com>
Co-authored-by: Thibault <thibault_poisson@orange.fr>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: David Blythe <49919035+writeDavid@users.noreply.github.com>
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
fix(stronghold): change wrong argument name for `remove` (#422)
fix(window-state): correctly set decoration state if no saved state exists, fixes #421 (#424)
fix(stronghold): return null if there is no record (#129)
fix(window-state): propagate promise (#435)
closes #432
fix(window-state): manual default implentation (#425)
fix(window-state): manual default implentation, closes #421
fix(deps): update rust crate iota-crypto to 0.21 (#438)
fix readme example (#447)
fix: handle recursive directory correctly (#455)
fix(deps): update rust crate sqlx to 0.7. plugin-sql msrv is now 1.65 (#464)
fix(persisted-scope): separately save asset protocol patterns (#459)
fix(deps): update rust crate iota-crypto to 0.22 (#475)
fix(deps): update tauri monorepo to v1.4.0 (#482)
resolve to v15.1.0 (#489)
fix(deps): update rust crate iota-crypto to 0.23 (#495)
2023-07-19 14:50:43 -03:00
Amr Bashir 52ef0addd8 feat(shell): ensure launched processes are detached (#463)
* feat(shell): ensure launched processes are detached

ref: https://github.com/tauri-apps/tauri/issues/6849

* change file
2023-07-04 14:30:22 +03:00