Core/WindowManager.ps1

# Core\WindowManager.ps1
# Shared WebView2 window launcher — used by every Posh app

function New-PoshWindow {
    <#
    .SYNOPSIS
        Launch a WebView2 window pointing at a localhost port.
    .DESCRIPTION
        Generates a PS 5.1 script that creates a borderless WebView2 window,
        saves it to a temp file, and spawns it as a hidden subprocess.

        This is the single shared launcher for every Posh application.
        Apps call this instead of managing their own WebView2 boilerplate.

        Returns the spawned System.Diagnostics.Process object so the caller
        can register its PID with Update-PoshPortPID.

    .PARAMETER AppName
        Name of the application (used for window title and user-data folder).

    .PARAMETER Port
        Localhost port the WebView2 window will navigate to.

    .PARAMETER Width
        Window width in pixels. Default: 1200.

    .PARAMETER Height
        Window height in pixels. Default: 800.

    .PARAMETER Borderless
        Remove the standard window chrome (title bar / borders).

    .EXAMPLE
        $proc = New-PoshWindow -AppName "PoshConsole" -Port 49152
        Update-PoshPortPID -Port 49152 -PID $proc.Id

    .EXAMPLE
        $proc = New-PoshWindow -AppName "PoshPad" -Port 49153 -Width 1400 -Height 900 -Borderless
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$AppName,

        [Parameter(Mandatory)]
        [int]$Port,

        [int]$Width      = 1200,
        [int]$Height     = 800,
        [switch]$Borderless
    )

    # Ensure WebView2 is ready
    $dllPath = Get-WebView2DllPath
    if (-not $dllPath) {
        Write-Error "WebView2 DLLs not found. Run Install-PoshDependencies first."
        return $null
    }

    $formStyle = if ($Borderless) {
        "`$form.FormBorderStyle = 'None'"
    } else {
        ""
    }

    # Build the PS 5.1 window script
    $windowScript = @"
# $AppName WebView2 Window — auto-generated by PoshDE, runs in PS 5.1
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

`$dllPath = '$dllPath'
Add-Type -Path (Join-Path `$dllPath 'Microsoft.Web.WebView2.Core.dll')
Add-Type -Path (Join-Path `$dllPath 'Microsoft.Web.WebView2.WinForms.dll')

# WebView2 requires a writable per-app user-data folder
`$userDataFolder = Join-Path `$env:LOCALAPPDATA '$AppName\WebView2'
if (-not (Test-Path `$userDataFolder)) {
    New-Item -Path `$userDataFolder -ItemType Directory -Force | Out-Null
}

`$form = New-Object System.Windows.Forms.Form
`$form.Text = '$AppName'
`$form.Width = $Width
`$form.Height = $Height
`$form.StartPosition = 'CenterScreen'
`$form.BackColor = [System.Drawing.Color]::FromArgb(10, 10, 10)
$formStyle

`$webView = New-Object Microsoft.Web.WebView2.WinForms.WebView2
`$webView.Dock = 'Fill'
`$webView.DefaultBackgroundColor = [System.Drawing.Color]::FromArgb(10, 10, 10)
`$webView.CreationProperties = New-Object Microsoft.Web.WebView2.WinForms.CoreWebView2CreationProperties
`$webView.CreationProperties.UserDataFolder = `$userDataFolder

`$form.Controls.Add(`$webView)

`$webView.Add_CoreWebView2InitializationCompleted({
    param(`$sender, `$e)
    if (`$e.IsSuccess) {
        `$webView.CoreWebView2.Navigate('http://localhost:$Port')
    } else {
        [System.Windows.Forms.MessageBox]::Show(
            "WebView2 failed to initialize:`n`$(`$e.InitializationException.Message)",
            '$AppName — Error'
        )
    }
})

`$form.Add_Shown({
    `$webView.EnsureCoreWebView2Async(`$null)
})

`$form.Add_FormClosing({
    try { `$webView.Dispose() } catch {}
})

[System.Windows.Forms.Application]::EnableVisualStyles()
[System.Windows.Forms.Application]::Run(`$form)
"@


    # Write to a per-app temp script
    $tempScript = Join-Path $env:TEMP "$($AppName)_PoshWindow_$Port.ps1"
    $windowScript | Set-Content -Path $tempScript -Encoding UTF8

    # Spawn in PS 5.1 with no visible console
    $proc = Start-Process -FilePath "powershell.exe" `
        -ArgumentList "-NoProfile", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-File", "`"$tempScript`"" `
        -PassThru

    Write-Verbose "Launched $AppName window (PID $($proc.Id)) on port $Port"
    return $proc
}

Write-Verbose "WindowManager loaded"