Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6cdab2fde1 | ||
|
|
6239780978 | ||
|
|
67cf3044f1 | ||
|
|
66be35c3d4 | ||
|
|
046cfe62b8 |
No files matched your search
@@ -1866,6 +1866,20 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embed-resource"
|
||||||
|
version = "3.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fbfdaacccebec3b28e4866b8973543c7647797db5ada1bdab552e48fe665fbbd"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"memchr",
|
||||||
|
"rustc_version",
|
||||||
|
"toml",
|
||||||
|
"vswhom",
|
||||||
|
"winreg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "endi"
|
name = "endi"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
@@ -4359,7 +4373,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pstr-android"
|
name = "pstr-android"
|
||||||
version = "1.1.1"
|
version = "1.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_logger",
|
"android_logger",
|
||||||
"jni 0.21.1",
|
"jni 0.21.1",
|
||||||
@@ -4378,7 +4392,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pstr-app"
|
name = "pstr-app"
|
||||||
version = "1.1.1"
|
version = "1.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -4387,6 +4401,7 @@ dependencies = [
|
|||||||
"eframe",
|
"eframe",
|
||||||
"egui",
|
"egui",
|
||||||
"egui-phosphor",
|
"egui-phosphor",
|
||||||
|
"embed-resource",
|
||||||
"futures",
|
"futures",
|
||||||
"image",
|
"image",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
@@ -4409,7 +4424,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pstr-cli"
|
name = "pstr-cli"
|
||||||
version = "1.1.1"
|
version = "1.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -4427,7 +4442,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pstr-core"
|
name = "pstr-core"
|
||||||
version = "1.1.1"
|
version = "1.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"directories",
|
"directories",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -4445,7 +4460,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pstr-meta"
|
name = "pstr-meta"
|
||||||
version = "1.1.1"
|
version = "1.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pstr-core",
|
"pstr-core",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
@@ -4458,7 +4473,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pstr-player"
|
name = "pstr-player"
|
||||||
version = "1.1.1"
|
version = "1.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"libloading",
|
"libloading",
|
||||||
@@ -4473,7 +4488,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pstr-stream"
|
name = "pstr-stream"
|
||||||
version = "1.1.1"
|
version = "1.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -6248,6 +6263,26 @@ version = "0.9.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vswhom"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"vswhom-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vswhom-sys"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@@ -7161,6 +7196,16 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winreg"
|
||||||
|
version = "0.55.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen"
|
name = "wit-bindgen"
|
||||||
version = "0.57.1"
|
version = "0.57.1"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "1.1.1"
|
version = "1.1.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/narrrl/proton-stream"
|
repository = "https://github.com/narrrl/proton-stream"
|
||||||
@@ -103,6 +103,8 @@ dbus = "0.9"
|
|||||||
windows-sys = "0.61"
|
windows-sys = "0.61"
|
||||||
# Toasts on Windows. Linux notifications go over the `dbus` above.
|
# Toasts on Windows. Linux notifications go over the `dbus` above.
|
||||||
tauri-winrt-notification = "0.8"
|
tauri-winrt-notification = "0.8"
|
||||||
|
# The exe's own icon resource, which is what Explorer and a taskbar pin draw.
|
||||||
|
embed-resource = "3"
|
||||||
rpassword = "7"
|
rpassword = "7"
|
||||||
libloading = "0.8"
|
libloading = "0.8"
|
||||||
lru = "0.18"
|
lru = "0.18"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.narl.protonstream.ui.theme
|
|||||||
|
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
@@ -9,6 +10,7 @@ import androidx.compose.material3.Button
|
|||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FilledTonalButton
|
import androidx.compose.material3.FilledTonalButton
|
||||||
|
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.NavigationBarItemDefaults
|
import androidx.compose.material3.NavigationBarItemDefaults
|
||||||
import androidx.compose.material3.NavigationDrawerItemDefaults
|
import androidx.compose.material3.NavigationDrawerItemDefaults
|
||||||
@@ -18,14 +20,18 @@ import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteDefaul
|
|||||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteItemColors
|
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteItemColors
|
||||||
import androidx.compose.material3.SliderState
|
import androidx.compose.material3.SliderState
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.material3.minimumInteractiveComponentSize
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.geometry.CornerRadius
|
import androidx.compose.ui.geometry.CornerRadius
|
||||||
import androidx.compose.ui.geometry.Size
|
import androidx.compose.ui.geometry.Size
|
||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,17 +74,30 @@ internal fun AccentButton(
|
|||||||
content: @Composable RowScope.() -> Unit,
|
content: @Composable RowScope.() -> Unit,
|
||||||
) {
|
) {
|
||||||
val shape = MaterialTheme.shapes.small
|
val shape = MaterialTheme.shapes.small
|
||||||
Button(
|
// The button pads itself out to the 48dp minimum touch target, and a
|
||||||
onClick = onClick,
|
// background on its modifier fills that whole target — 8dp taller than
|
||||||
// Only while it is live: a disabled button keeps Material's flat
|
// the 40dp container every other button draws. So the padding is taken
|
||||||
// disabled container, because a greyed control that still wears the
|
// here, outside the ramp, and the button inside is told not to add its
|
||||||
// one strong colour in the window reads as pressable.
|
// own. The box hands its size down, so a `fillMaxWidth` still reaches it.
|
||||||
modifier = if (enabled) modifier.background(accentBrush(), shape) else modifier,
|
Box(
|
||||||
enabled = enabled,
|
modifier.minimumInteractiveComponentSize(),
|
||||||
shape = shape,
|
contentAlignment = Alignment.Center,
|
||||||
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent),
|
propagateMinConstraints = true,
|
||||||
content = content,
|
) {
|
||||||
)
|
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides Dp.Unspecified) {
|
||||||
|
Button(
|
||||||
|
onClick = onClick,
|
||||||
|
// Only while it is live: a disabled button keeps Material's flat
|
||||||
|
// disabled container, because a greyed control that still wears the
|
||||||
|
// one strong colour in the window reads as pressable.
|
||||||
|
modifier = if (enabled) Modifier.background(accentBrush(), shape) else Modifier,
|
||||||
|
enabled = enabled,
|
||||||
|
shape = shape,
|
||||||
|
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent),
|
||||||
|
content = content,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 813 KiB After Width: | Height: | Size: 813 KiB |
|
Before Width: | Height: | Size: 769 KiB After Width: | Height: | Size: 768 KiB |
|
Before Width: | Height: | Size: 807 KiB After Width: | Height: | Size: 806 KiB |
|
Before Width: | Height: | Size: 638 KiB After Width: | Height: | Size: 631 KiB |
|
Before Width: | Height: | Size: 678 KiB After Width: | Height: | Size: 669 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
@@ -34,6 +34,9 @@ directories.workspace = true
|
|||||||
chrono.workspace = true
|
chrono.workspace = true
|
||||||
souvlaki.workspace = true
|
souvlaki.workspace = true
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
embed-resource.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
skrifa.workspace = true
|
skrifa.workspace = true
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//! Compiles `proton-stream.rc` into the Windows exe; nothing on any other
|
||||||
|
//! target. `rc.exe` on an MSVC build, mingw's `windres` on the cross build
|
||||||
|
//! from Linux.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("cargo:rerun-if-changed=proton-stream.rc");
|
||||||
|
println!("cargo:rerun-if-changed=../../packaging/windows/proton-stream.ico");
|
||||||
|
if std::env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("windows") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Only the GUI gets the icon; `pstr` is a console tool.
|
||||||
|
embed_resource::compile_for("proton-stream.rc", ["proton-stream"], embed_resource::NONE)
|
||||||
|
.manifest_optional()
|
||||||
|
.expect("compile the icon resource");
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// The exe's icon. The window sets one at runtime too, but that only lasts as
|
||||||
|
// long as the window: Explorer, the Start menu and a taskbar pin read the icon
|
||||||
|
// out of the file, and without this one they fall back to the generic one.
|
||||||
|
1 ICON "../../packaging/windows/proton-stream.ico"
|
||||||
@@ -146,6 +146,54 @@ and [B44](#b44--r8-broke-the-app-under-instrumentation-in-five-places).
|
|||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
### B63 — a taskbar pin on Windows lost its icon
|
||||||
|
|
||||||
|
**Symptom.** Proton Stream pinned to the Windows taskbar showed its icon at
|
||||||
|
first, then after a while — reliably after an update — the generic program
|
||||||
|
icon.
|
||||||
|
|
||||||
|
**Cause.** Two, each enough on its own. `proton-stream.exe` carried no icon
|
||||||
|
resource: the window sets one at runtime, which is what a pin shows while the
|
||||||
|
icon cache still holds it, but a pin made from the running window points at
|
||||||
|
the exe, and once the cache is rebuilt the exe has nothing to give. A pin made
|
||||||
|
from the Start Menu shortcut instead took the shortcut's `Icon`, which Windows
|
||||||
|
Installer keeps in `C:\Windows\Installer\{ProductCode}`. Every upgrade has a
|
||||||
|
new ProductCode and deletes the old product's folder, icon included.
|
||||||
|
|
||||||
|
**Fix.** `crates/pstr-app/build.rs` compiles `proton-stream.rc`, which embeds
|
||||||
|
`packaging/windows/proton-stream.ico`, into the GUI exe: `rc.exe` on MSVC,
|
||||||
|
mingw's `windres` on the cross build. Both installer definitions drop the
|
||||||
|
shortcut's `Icon` (and the WiX one `Advertise`), so the shortcut shows the
|
||||||
|
exe's icon too. A pin that already lost its icon keeps the dead reference;
|
||||||
|
unpin and pin again once.
|
||||||
|
|
||||||
|
**Verified.** `objdump -p` on the cross-built exe lists the `RT_ICON` entries,
|
||||||
|
all seven sizes. `msiinfo export … Shortcut` on a wixl build has an empty
|
||||||
|
`Icon_` column. Not yet checked on a Windows taskbar across an upgrade.
|
||||||
|
|
||||||
|
### B62 — an MSI upgrade left the app without libmpv
|
||||||
|
|
||||||
|
**Symptom.** Installing a new `.msi` over an old one ended with an app that
|
||||||
|
would not start for want of mpv. Installing the same `.msi` a second time
|
||||||
|
fixed it.
|
||||||
|
|
||||||
|
**Cause.** Both installers remove the old product early — the wixl one at
|
||||||
|
`RemoveExistingProducts` after `InstallInitialize`, WiX's `MajorUpgrade` by
|
||||||
|
default after `InstallValidate` — but costing runs before either, at
|
||||||
|
`CostFinalize`. Costing found the old `libmpv-2.dll` on disk with the same
|
||||||
|
version as the new one, since mpv is pinned, and decided not to copy it. Then
|
||||||
|
removing the old product deleted it. The second install found no DLL on disk,
|
||||||
|
so it copied one.
|
||||||
|
|
||||||
|
**Fix.** `REINSTALLMODE=amus` in both installer definitions, which copies every
|
||||||
|
file whatever is on disk. Every file is private to the install directory, so
|
||||||
|
the forced overwrite can downgrade nothing shared.
|
||||||
|
|
||||||
|
**Verified.** `msiinfo export … InstallExecuteSequence` on a wixl build shows
|
||||||
|
`FileCost` 900 and `CostFinalize` 1000 ahead of `RemoveExistingProducts` 1501,
|
||||||
|
and `msiinfo export … Property` has `REINSTALLMODE amus`. Not yet checked as an
|
||||||
|
upgrade on Windows.
|
||||||
|
|
||||||
### B61 — later seasons were captioned with season one's episode names
|
### B61 — later seasons were captioned with season one's episode names
|
||||||
|
|
||||||
**Symptom.** On a 42-title AniList library, Attack on Titan seasons 2–4 and
|
**Symptom.** On a 42-title AniList library, Attack on Titan seasons 2–4 and
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
# builds from the registry alone.
|
# builds from the registry alone.
|
||||||
|
|
||||||
pkgname=proton-stream
|
pkgname=proton-stream
|
||||||
pkgver=1.1.1
|
pkgver=1.1.3
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Netflix-style desktop client for Proton Drive public links: browse and stream a share"
|
pkgdesc="Netflix-style desktop client for Proton Drive public links: browse and stream a share"
|
||||||
arch=('x86_64')
|
arch=('x86_64')
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ The `.icns` is rasterized from `io.narl.proton-stream.svg` when `rsvg-convert` o
|
|||||||
| `io.narl.proton-stream.desktop` / `.svg` | Freedesktop entry and icon |
|
| `io.narl.proton-stream.desktop` / `.svg` | Freedesktop entry and icon |
|
||||||
| `macos/Info.plist.in` | `.app` bundle plist; `@VERSION@`/`@BIN@`/`@APP_ID@` substituted at build time |
|
| `macos/Info.plist.in` | `.app` bundle plist; `@VERSION@`/`@BIN@`/`@APP_ID@` substituted at build time |
|
||||||
| `windows/proton-stream.wxs` | WiX v4+ installer definition |
|
| `windows/proton-stream.wxs` | WiX v4+ installer definition |
|
||||||
| `windows/proton-stream.ico` | MSI and shortcut icon, rasterized from the SVG |
|
| `windows/proton-stream.ico` | Exe and Add/Remove Programs icon, rasterized from the SVG; `crates/pstr-app/build.rs` compiles it into `proton-stream.exe` |
|
||||||
| `windows/license.rtf` | Fallback for the installer's license dialog; the repo's own `LICENSE` is preferred when it exists |
|
| `windows/license.rtf` | Fallback for the installer's license dialog; the repo's own `LICENSE` is preferred when it exists |
|
||||||
|
|
||||||
The Debian `control` file has no template — `scripts/build.sh` writes it, because
|
The Debian `control` file has no template — `scripts/build.sh` writes it, because
|
||||||
|
|||||||
@@ -78,6 +78,15 @@
|
|||||||
<RemoveExistingProducts After="InstallInitialize" />
|
<RemoveExistingProducts After="InstallInitialize" />
|
||||||
</InstallExecuteSequence>
|
</InstallExecuteSequence>
|
||||||
|
|
||||||
|
<!-- Copy every file on an upgrade, whatever is on disk. Costing runs
|
||||||
|
before RemoveExistingProducts, so it sees the old libmpv-2.dll — the
|
||||||
|
same version, since mpv is pinned — and decides not to copy it. The
|
||||||
|
removal of the old product then deletes it, and the upgrade ends with
|
||||||
|
no DLL: "mpv missing" until a second install, which finds nothing on
|
||||||
|
disk and copies it. Every file here is private to INSTALLDIR, so
|
||||||
|
overwriting unconditionally downgrades nothing shared. -->
|
||||||
|
<Property Id="REINSTALLMODE" Value="amus" />
|
||||||
|
|
||||||
<Media Id="1" Cabinet="proton_stream.cab" EmbedCab="yes" />
|
<Media Id="1" Cabinet="proton_stream.cab" EmbedCab="yes" />
|
||||||
|
|
||||||
<Icon Id="proton-stream.ico" SourceFile="$(var.IconFile)" />
|
<Icon Id="proton-stream.ico" SourceFile="$(var.IconFile)" />
|
||||||
@@ -98,14 +107,19 @@
|
|||||||
and writes the advertised form anyway, with the feature name in
|
and writes the advertised form anyway, with the feature name in
|
||||||
Shortcut/Target. What selects the non-advertised form is being
|
Shortcut/Target. What selects the non-advertised form is being
|
||||||
a child of the Component rather than of the File, plus an
|
a child of the Component rather than of the File, plus an
|
||||||
explicit formatted Target. Keep it out of the <File>. -->
|
explicit formatted Target. Keep it out of the <File>.
|
||||||
|
|
||||||
|
No Icon either. A shortcut's Icon is copied to
|
||||||
|
C:\Windows\Installer\{ProductCode}, and every upgrade has a
|
||||||
|
new ProductCode and deletes the old folder — taking the icon
|
||||||
|
of every taskbar pin made from the shortcut with it. Without
|
||||||
|
one, the shortcut shows the exe's own icon resource. -->
|
||||||
<Shortcut Id="StartMenuShortcut"
|
<Shortcut Id="StartMenuShortcut"
|
||||||
Directory="ProgramMenuFolder"
|
Directory="ProgramMenuFolder"
|
||||||
Name="Proton Stream"
|
Name="Proton Stream"
|
||||||
Description="Browse and stream a Proton Drive public link"
|
Description="Browse and stream a Proton Drive public link"
|
||||||
Target="[INSTALLDIR]proton-stream.exe"
|
Target="[INSTALLDIR]proton-stream.exe"
|
||||||
WorkingDirectory="INSTALLDIR"
|
WorkingDirectory="INSTALLDIR" />
|
||||||
Icon="proton-stream.ico" />
|
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- The CLI, and the PATH entry that makes it worth installing. Tied
|
<!-- The CLI, and the PATH entry that makes it worth installing. Tied
|
||||||
|
|||||||
@@ -26,6 +26,15 @@
|
|||||||
DowngradeErrorMessage="A newer version of Proton Stream is already installed." />
|
DowngradeErrorMessage="A newer version of Proton Stream is already installed." />
|
||||||
<MediaTemplate EmbedCab="yes" />
|
<MediaTemplate EmbedCab="yes" />
|
||||||
|
|
||||||
|
<!-- Copy every file on an upgrade, whatever is on disk. Costing runs
|
||||||
|
before RemoveExistingProducts, so it sees the old libmpv-2.dll — the
|
||||||
|
same version, since mpv is pinned — and decides not to copy it. The
|
||||||
|
removal of the old product then deletes it, and the upgrade ends with
|
||||||
|
no DLL: "mpv missing" until a second install, which finds nothing on
|
||||||
|
disk and copies it. Every file here is private to INSTALLFOLDER, so
|
||||||
|
overwriting unconditionally downgrades nothing shared. -->
|
||||||
|
<Property Id="REINSTALLMODE" Value="amus" />
|
||||||
|
|
||||||
<Icon Id="AppIcon" SourceFile="$(var.IconFile)" />
|
<Icon Id="AppIcon" SourceFile="$(var.IconFile)" />
|
||||||
<Property Id="ARPPRODUCTICON" Value="AppIcon" />
|
<Property Id="ARPPRODUCTICON" Value="AppIcon" />
|
||||||
<Property Id="ARPURLINFOABOUT" Value="https://github.com/narrrl/proton-stream" />
|
<Property Id="ARPURLINFOABOUT" Value="https://github.com/narrrl/proton-stream" />
|
||||||
@@ -45,12 +54,16 @@
|
|||||||
<ComponentGroup Id="AppComponents" Directory="INSTALLFOLDER">
|
<ComponentGroup Id="AppComponents" Directory="INSTALLFOLDER">
|
||||||
<Component Guid="623c8cb8-b826-4d57-a054-e5be56f24c19">
|
<Component Guid="623c8cb8-b826-4d57-a054-e5be56f24c19">
|
||||||
<File Id="AppExe" Source="$(var.BinDir)\proton-stream.exe" KeyPath="yes" />
|
<File Id="AppExe" Source="$(var.BinDir)\proton-stream.exe" KeyPath="yes" />
|
||||||
|
<!-- Not advertised, and no Icon: either one puts the shortcut's icon
|
||||||
|
in C:\Windows\Installer\{ProductCode}, which the next upgrade
|
||||||
|
deletes along with the icon of every taskbar pin made from the
|
||||||
|
shortcut. This way it shows the exe's own icon resource. -->
|
||||||
<Shortcut Id="StartMenuShortcut"
|
<Shortcut Id="StartMenuShortcut"
|
||||||
Directory="ProgramMenuFolder"
|
Directory="ProgramMenuFolder"
|
||||||
Name="Proton Stream"
|
Name="Proton Stream"
|
||||||
Description="Browse and stream a Proton Drive public link"
|
Description="Browse and stream a Proton Drive public link"
|
||||||
Icon="AppIcon"
|
Target="[#AppExe]"
|
||||||
Advertise="yes" />
|
WorkingDirectory="INSTALLFOLDER" />
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- The CLI, and the PATH entry that makes it worth installing. Tied to
|
<!-- The CLI, and the PATH entry that makes it worth installing. Tied to
|
||||||
|
|||||||