| ... | @@ -391,14 +391,33 @@ const mobileEndorsementRows = [ | ... | @@ -391,14 +391,33 @@ const mobileEndorsementRows = [ |
| 391 | | 391 | |
| 392 | <script> | 392 | <script> |
| 393 | import { fetchLatestRelease, RELEASES_URL, type ReleaseAsset } from "../lib/releases"; | 393 | import { fetchLatestRelease, RELEASES_URL, type ReleaseAsset } from "../lib/releases"; |
| | 394 | import { macArchFromGpuRenderer } from "../lib/macArch"; |
| 394 | | 395 | |
| 395 | type Platform = { os: "mac" | "win" | "linux"; label: string; arch?: string }; | 396 | type Platform = { os: "mac" | "win" | "linux"; label: string; arch?: string }; |
| 396 | | 397 | |
| | 398 | // navigator.userAgent reports "Intel Mac OS X" on both Intel and Apple Silicon |
| | 399 | // Macs, so probe the GPU renderer instead: Apple Silicon exposes an "Apple" GPU. |
| | 400 | function detectMacArch(): "arm64" | "x64" { |
| | 401 | try { |
| | 402 | const canvas = document.createElement("canvas"); |
| | 403 | const gl = (canvas.getContext("webgl") || |
| | 404 | canvas.getContext("experimental-webgl")) as WebGLRenderingContext | null; |
| | 405 | const debugInfo = gl?.getExtension("WEBGL_debug_renderer_info"); |
| | 406 | if (gl && debugInfo) { |
| | 407 | const renderer = String(gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) ?? ""); |
| | 408 | return macArchFromGpuRenderer(renderer); |
| | 409 | } |
| | 410 | } catch { |
| | 411 | // fall through to the default below |
| | 412 | } |
| | 413 | return macArchFromGpuRenderer(""); |
| | 414 | } |
| | 415 | |
| 397 | function detectPlatform(): Platform | null { | 416 | function detectPlatform(): Platform | null { |
| 398 | const ua = navigator.userAgent; | 417 | const ua = navigator.userAgent; |
| 399 | if (/Win/i.test(ua)) return { os: "win", label: "Download for Windows" }; | 418 | if (/Win/i.test(ua)) return { os: "win", label: "Download for Windows" }; |
| 400 | if (/Mac/i.test(ua)) { | 419 | if (/Mac/i.test(ua)) { |
| 401 | return { os: "mac", label: "Download for macOS", arch: "arm64" }; | 420 | return { os: "mac", label: "Download for macOS", arch: detectMacArch() }; |
| 402 | } | 421 | } |
| 403 | if (/Linux/i.test(ua)) return { os: "linux", label: "Download for Linux" }; | 422 | if (/Linux/i.test(ua)) return { os: "linux", label: "Download for Linux" }; |
| 404 | return null; | 423 | return null; |