Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ py -3.12 -c "from app.tts import ENGINE_CATALOG; v=ENGINE_CATALOG['chatterbox'][
```

After installation, verify the monitor identifies CUDA/NVIDIA, the app opens in
a dedicated maximized window without a visible console, the desktop shortcut
uses `parroty.ico`, all eight voices appear, previews work, and `stop.bat` shuts
down port 5000.
a dedicated maximized window without a visible console, and closing that app
window with X stops the Flask listener and releases port 5000. Also verify the
desktop shortcut uses `parroty.ico`, all eight voices appear, previews work, and
`stop.bat` still shuts down port 5000 as a fallback.

Before publishing, review `README.md`, `Quick Start Readme.txt`, `BUILD.md`,
`RELEASE_NOTES.md`, and the voice attribution. No version bump or GitHub Release
Expand Down
8 changes: 5 additions & 3 deletions Quick Start Readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ launch_parroty.pyw, and the app folder:
5. Save with the exact .bat filename shown.

The eight bundled Chatterbox voices already live under app\assets\voices.
No API key or separate voice download is required.
No API key or separate voice download is required. Closing the dedicated
Parroty Chrome/Edge app window with X automatically stops the hidden backend.

========================================================================
FILE: install_all.bat
Expand Down Expand Up @@ -140,7 +141,8 @@ exit /b 0

1. Run install_all.bat once.
2. Start Parroty with run.bat or the desktop shortcut.
3. Use stop.bat to stop the hidden backend.
4. Use run_debug.bat only for troubleshooting.
3. Close the Parroty app window with X to stop the hidden backend automatically.
4. Use stop.bat only if the window is already gone or a forced stop is needed.
5. Use run_debug.bat only for troubleshooting.

Do not commit the generated BAT files. They are local/package conveniences.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,11 @@ installed). Press **Ctrl+C** to stop.
`Quick Start Readme.txt`, or use a packaged Windows ZIP that already includes
them. `run.bat` starts the backend windowlessly through `pythonw.exe`, opens
Parroty in a dedicated maximized Chrome/Edge app window, and silently creates or
refreshes the desktop shortcut. Output goes to `parroty.log`; use `stop.bat` to
shut down the hidden server. These `.bat` files are deliberately ignored by Git.
refreshes the desktop shortcut. Closing that Parroty app window with **X** now
automatically stops the hidden Flask backend, the same result as running
`stop.bat`. Output goes to `parroty.log`; `stop.bat` remains available as a
fallback if the window is already gone or the backend needs to be forced closed.
These `.bat` files are deliberately ignored by Git.

Starting again later needs no reinstall — setup is one-time. Open a terminal,
`cd` into the Parroty folder, activate the venv, and run the server:
Expand Down
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ No version number is assigned to this update.
- Added the bottom-left CPU/GPU/VRAM system monitor.
- Added hidden background launching with persistent `parroty.log` diagnostics.
- Added a dedicated maximized Chrome/Edge app window using its own browser profile.
- Closing the dedicated Parroty app window now automatically stops the hidden
Flask backend, matching `stop.bat` behavior without affecting normal browser windows.
- Added desktop-shortcut creation using the Parroty icon.
- Corrected hidden-launch template/static resolution.
- Kept narration workers GPU-enabled when the app window is hidden or inactive.
Expand Down
59 changes: 58 additions & 1 deletion parroty_window.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
param(
[string]$Url = "http://127.0.0.1:5000",
[string]$Root = $PSScriptRoot
[string]$Root = $PSScriptRoot,
[int]$Port = 5000
)

$ErrorActionPreference = "SilentlyContinue"
Expand All @@ -21,6 +22,52 @@ function Find-Browser {
return $null
}

function Get-ParrotyBackendPids {
param([int]$ListenerPort)

# Capture the exact process already listening for Parroty before opening the
# browser. When the app window closes we stop only these recorded PIDs, never
# an unrelated process that might later reuse the port.
$ids = [System.Collections.Generic.HashSet[int]]::new()

try {
Get-NetTCPConnection -LocalPort $ListenerPort -State Listen -ErrorAction Stop |
ForEach-Object {
if ($_.OwningProcess -gt 0) {
[void]$ids.Add([int]$_.OwningProcess)
}
}
} catch {}

# Fallback for systems where Get-NetTCPConnection is unavailable or restricted.
if ($ids.Count -eq 0) {
try {
$escapedPort = [regex]::Escape([string]$ListenerPort)
$pattern = "^\s*TCP\s+\S+:$escapedPort\s+\S+\s+LISTENING\s+(\d+)\s*$"
foreach ($line in (& netstat.exe -ano -p tcp 2>$null)) {
if ($line -match $pattern) {
[void]$ids.Add([int]$Matches[1])
}
}
} catch {}
}

return @($ids)
}

function Stop-ParrotyBackend {
param([int[]]$ProcessIds)

foreach ($backendProcessId in $ProcessIds) {
if ($backendProcessId -le 0 -or $backendProcessId -eq $PID) { continue }
try {
Get-Process -Id $backendProcessId -ErrorAction Stop | Out-Null
Stop-Process -Id $backendProcessId -Force -ErrorAction Stop
try { Wait-Process -Id $backendProcessId -Timeout 5 -ErrorAction SilentlyContinue } catch {}
} catch {}
}
}

function Maximize-ParrotyWindow {
param(
[System.Diagnostics.Process]$InitialProcess,
Expand Down Expand Up @@ -92,10 +139,17 @@ public static class ParrotyNativeWindow {

$browser = Find-Browser
if (-not $browser) {
# A normal browser tab cannot be reliably monitored for its close event, so
# retain the browser fallback without automatic backend shutdown.
Start-Process $Url
exit 0
}

# Record the currently healthy Parroty listener before starting the app window.
# This mirrors stop.bat when the window later closes, while avoiding broad
# process-name matching or interference with normal browser windows.
$backendPids = @(Get-ParrotyBackendPids -ListenerPort $Port)

# A dedicated Chromium profile prevents an existing normal browser session from
# restoring Parroty to a remembered windowed size. This is the same launcher
# pattern used by Stemmy.
Expand All @@ -122,5 +176,8 @@ if (-not $process) {
$windowProcess = Maximize-ParrotyWindow -InitialProcess $process -BrowserPath $browser -LaunchTime $launchTime
Set-Content -LiteralPath (Join-Path $Root ".parroty.browser.pid") -Value $windowProcess.Id

# Wait for the dedicated Parroty app window—not the user's normal browser—to be
# closed with X. Closing it is treated the same as running stop.bat.
try { $windowProcess.WaitForExit() } catch {}
Remove-Item -LiteralPath (Join-Path $Root ".parroty.browser.pid") -Force -ErrorAction SilentlyContinue
Stop-ParrotyBackend -ProcessIds $backendPids