windows / build (aarch64-pc-windows-msvc) (push) Canceled after 0s
windows / build (x86_64-pc-windows-msvc) (push) Canceled after 0s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Canceled after 0s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Canceled after 0s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Canceled after 0s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 0s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Canceled after 0s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Canceled after 0s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Canceled after 0s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Canceled after 0s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Canceled after 0s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Canceled after 0s
docker / build-push-arm64cross (push) Canceled after 0s
docker / deploy-docs (push) Canceled after 0s
decky / build-publish (push) Canceled after 0s
deb / build-publish (push) Canceled after 0s
deb / build-publish-host (push) Canceled after 0s
deb / build-publish-client-arm64 (push) Canceled after 0s
ci / rust (push) Canceled after 0s
ci / rust-arm64 (push) Canceled after 0s
ci / web (push) Canceled after 0s
ci / docs-site (push) Canceled after 0s
ci / bench (push) Canceled after 0s
arch / build-publish (push) Canceled after 0s
apple / swift (push) Canceled after 0s
apple / screenshots (push) Canceled after 0s
android / android (push) Canceled after 0s
WP4 / D2. Protocol activation of a full-trust packaged app delivers the URI as the command line, so a browser prompt, `start punktfunk://…` and a written `.lnk` all arrive the same way — as a positional argument, the same door the Linux shell uses. What Windows does not give us is single-instancing: unlike GApplication, a second activation is simply a second process. So the first instance claims the named mutex `unom.punktfunk.client` and any later one hands its URL to the winner over `WM_COPYDATA` and exits — one window, and the link opens where the user's hosts already are. The hand-off retries while the primary's window is still coming up (a shortcut double-clicked during startup is the ordinary case), and a hand-off that finds nobody falls through so this process becomes the shell that opens it. A link is never silently dropped, which is also why the inbox is a queue: two shortcuts in quick succession are two links. Routing is the same four lines of translation as on Linux, because the decisions belong to `plan_from_link`: a resolved link becomes the call a tile click makes, with the same wake, trust and error surfaces. Never preempting a live session is checked here, since only this layer knows one is running. The manifest declares the protocol and an app execution alias rather than writing registry keys, so uninstall leaves nothing behind — and Windows' own "allow this app to handle punktfunk links?" prompt is the origin friction the design wants, not duplicated in-app. (Manifest comments are free of double hyphens: XML forbids them and makepri rejects the whole file, which is how the console flag broke the v0.15.0 build. A test parses the substituted manifest and asserts both declarations, so that can't rot silently.) "Create shortcut…" writes a `.lnk` targeting the ALIAS with the URL as an argument, not a `.url` internet shortcut: both work while the scheme is registered, only this one still works if it isn't, and targeting the alias keeps it valid across updates when the package path changes. Verified on the CI VM (192.168.1.133): clippy -D warnings clean and its tests green. Not yet exercised on glass — `start punktfunk://…` cold and with the app running, and a written shortcut, still want a real desktop session. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
115 lines
5.2 KiB
XML
115 lines
5.2 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--
|
|
MSIX package manifest for the punktfunk Windows client (WinUI 3 via windows-reactor).
|
|
|
|
This is a TEMPLATE: packaging/pack-msix.ps1 substitutes {VERSION} (4-part numeric, e.g.
|
|
0.2.137.0) and {PUBLISHER} (must EXACTLY equal the signing cert's subject DN — default
|
|
`CN=unom` for the self-signed CI cert; a real code-signing cert just passes its own subject).
|
|
|
|
Why this packages cleanly even though the app was built "unpackaged": windows-reactor calls
|
|
MddBootstrapInitialize2 with OnPackageIdentity_NOOP (crates/libs/reactor/src/app.rs), so under
|
|
MSIX package identity the App SDK bootstrapper is a no-op and the runtime is resolved from the
|
|
<PackageDependency> below instead. The framework family + min version mirror what the runner has
|
|
installed and what reactor pins (WINDOWSAPPSDK_RELEASE_MAJORMINOR = 0x20000 = 2.0 ->
|
|
Microsoft.WindowsAppRuntime.2).
|
|
|
|
Full-trust Win32 app (EntryPoint Windows.FullTrustApplication + runFullTrust) — it owns raw D3D11,
|
|
Win32 low-level input hooks, WASAPI and SDL3, none of which fit the UWP app container.
|
|
-->
|
|
<Package
|
|
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
|
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
|
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
|
|
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
|
IgnorableNamespaces="uap uap5 rescap">
|
|
|
|
<Identity
|
|
Name="unom.Punktfunk"
|
|
Publisher="{PUBLISHER}"
|
|
Version="{VERSION}"
|
|
ProcessorArchitecture="{ARCH}" />
|
|
|
|
<Properties>
|
|
<DisplayName>Punktfunk</DisplayName>
|
|
<PublisherDisplayName>unom</PublisherDisplayName>
|
|
<Logo>Assets\StoreLogo.png</Logo>
|
|
</Properties>
|
|
|
|
<Dependencies>
|
|
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.26100.0" />
|
|
<PackageDependency
|
|
Name="Microsoft.WindowsAppRuntime.2"
|
|
MinVersion="2.2.0.0"
|
|
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
|
</Dependencies>
|
|
|
|
<Resources>
|
|
<Resource Language="en-us" />
|
|
</Resources>
|
|
|
|
<Applications>
|
|
<Application Id="Punktfunk" Executable="punktfunk-client.exe" EntryPoint="Windows.FullTrustApplication">
|
|
<uap:VisualElements
|
|
DisplayName="Punktfunk"
|
|
Description="Low-latency desktop and game streaming client"
|
|
BackgroundColor="transparent"
|
|
Square150x150Logo="Assets\Square150x150Logo.png"
|
|
Square44x44Logo="Assets\Square44x44Logo.png">
|
|
<uap:DefaultTile Square71x71Logo="Assets\Square71x71Logo.png" />
|
|
</uap:VisualElements>
|
|
<Extensions>
|
|
<!--
|
|
The punktfunk:// scheme (design/client-deep-links.md §4.2). Protocol activation of a
|
|
full trust packaged exe delivers the URI as the command line, so this and a shortcut
|
|
land in the same place: the positional URL parse in main().
|
|
|
|
Declared here rather than written to the registry on install, so uninstall leaves
|
|
nothing behind. Windows also asks the user before handing a scheme to a newly
|
|
installed app, which is the origin friction this design wants and does not duplicate.
|
|
-->
|
|
<uap:Extension Category="windows.protocol">
|
|
<uap:Protocol Name="punktfunk">
|
|
<uap:DisplayName>Punktfunk stream link</uap:DisplayName>
|
|
</uap:Protocol>
|
|
</uap:Extension>
|
|
<!--
|
|
An app execution alias so a written shortcut can target punktfunk-client.exe by name
|
|
from anywhere, without knowing the package install path (which changes on every
|
|
update). The .lnk writer uses exactly this.
|
|
-->
|
|
<uap5:Extension Category="windows.appExecutionAlias">
|
|
<uap5:AppExecutionAlias>
|
|
<uap5:ExecutionAlias Alias="punktfunk-client.exe" />
|
|
</uap5:AppExecutionAlias>
|
|
</uap5:Extension>
|
|
</Extensions>
|
|
</Application>
|
|
<!--
|
|
Second entry point: the couch/console UI, for an HTPC or a TV-attached box where the
|
|
desktop shell is the wrong first screen. Its own executable (punktfunk-console.exe)
|
|
because an MSIX Application entry cannot pass arguments to a full-trust exe; it hands
|
|
straight off to the session binary's controller-driven browse mode (host list,
|
|
pairing, settings, library) fullscreen.
|
|
|
|
NOTE: never write a double hyphen in this file. XML forbids it inside a comment, and
|
|
makepri rejects the whole manifest ("Appx manifest not found or is invalid") — which
|
|
is exactly how the console flag spelled out here broke the v0.15.0 MSIX build.
|
|
-->
|
|
<Application Id="PunktfunkConsole" Executable="punktfunk-console.exe"
|
|
EntryPoint="Windows.FullTrustApplication">
|
|
<uap:VisualElements
|
|
DisplayName="Punktfunk Console"
|
|
Description="Controller-driven couch interface for TVs and HTPCs"
|
|
BackgroundColor="transparent"
|
|
Square150x150Logo="Assets\Square150x150Logo.png"
|
|
Square44x44Logo="Assets\Square44x44Logo.png">
|
|
<uap:DefaultTile Square71x71Logo="Assets\Square71x71Logo.png" />
|
|
</uap:VisualElements>
|
|
</Application>
|
|
</Applications>
|
|
|
|
<Capabilities>
|
|
<rescap:Capability Name="runFullTrust" />
|
|
</Capabilities>
|
|
</Package>
|