Skip to content

feat(file-assoc): OS file handlers and launch-with-file (#664) - #716

Merged
fernandotonon merged 3 commits into
masterfrom
feat/file-associations-664
Jun 10, 2026
Merged

feat(file-assoc): OS file handlers and launch-with-file (#664)#716
fernandotonon merged 3 commits into
masterfrom
feat/file-associations-664

Conversation

@fernandotonon

@fernandotonon fernandotonon commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Slice A (Qt)AppLaunchHandler: parses GUI launch paths from argv, handles macOS QFileOpenEvent, single-instance via QLocalServer/QLocalSocket, and MainWindow::openLaunchFiles() with app.launch.file_open Sentry breadcrumbs. CLI (qtmesh info …) unchanged.
  • Slice B (macOS)CFBundleDocumentTypes + UTExportedTypeDeclarations for .mesh, .rsd, .tmd and common interchange formats; Homebrew cask postflight runs lsregister.
  • Slice C (Windows) — Inno Setup installer with per-user HKCU handlers; portable ZIP bundles register-windows-file-associations.ps1; WinGet manifest gains FileExtensions.
  • Slice D (Linux).desktop + XDG MIME XML in .deb with postinst (update-mime-database / update-desktop-database); snap desktop updated with MimeType= + %F.
  • Slice Escripts/verify-file-associations.sh in CI; README + website docs.

Closes #664 (child issues #665#669).

Test plan

  • ./build_local/bin/UnitTests --gtest_filter="AppLaunchHandler*" (7/7 pass)
  • ./scripts/verify-file-associations.sh
  • macOS: install DMG/cask → double-click .fbx → app opens with model
  • Windows: run installer or register-windows-file-associations.ps1 → Explorer Open With
  • Linux deb/snap: xdg-open model.fbx → QtMeshEditor in Open With list
  • Second instance with file path focuses existing window

Made with Cursor

Summary by CodeRabbit

  • New Features

    • Single‑instance behavior: opening a file focuses the running app and forwards files to it
    • Cross‑platform file-association support for many 3D formats (macOS, Windows, Linux)
  • Packaging

    • Windows: per‑user Inno Setup installer built and attached to releases; portable helper script for per‑user registration
    • Debian: desktop, MIME entries and postinst updates added
    • Homebrew cask: conditional postflight to refresh Finder/LaunchServices
  • Tests

    • Added unit tests and a verify-file-associations smoke-test script
  • Documentation

    • README and website docs updated with launch and file‑association guidance

Register QtMeshEditor as a 3D model handler on macOS, Windows, and Linux,
and route double-click / argv opens through AppLaunchHandler with
single-instance focus-and-load. Includes packaging, WinGet FileExtensions,
docs, and verification script.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2adf54fa-49bc-4398-85cd-475874fd293a

📥 Commits

Reviewing files that changed from the base of the PR and between 6503004 and 3e0d2a7.

📒 Files selected for processing (3)
  • .github/workflows/deploy.yml
  • scripts/register-windows-file-associations.ps1
  • scripts/verify-file-associations.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/deploy.yml

📝 Walkthrough

Walkthrough

Adds cross-platform file-association support: Qt single-instance launch routing, macOS plist types, Linux .desktop/MIME/postinst, Windows installer and per-user registration helper, CI verification, WinGet/Homebrew wiring, and documentation/README updates.

Changes

File Association Support: Qt, Windows, macOS, and Linux Integration

Layer / File(s) Summary
Qt launch handler & integration
src/AppLaunchHandler.h, src/AppLaunchHandler.cpp, src/AppLaunchHandler_test.cpp, src/CMakeLists.txt, src/main.cpp, src/mainwindow.h, src/mainwindow.cpp
New AppLaunchHandler detects CLI vs GUI, collects importable paths, forwards to running instances via QLocalSocket/Server, listens for incoming launches, installs a FileOpen event filter, and wires MainWindow::openLaunchFiles; includes unit tests and build wiring.
macOS bundle metadata & cask postflight
src/Info.plist.in, packaging/macos/homebrew-cask-postflight.rb, .github/workflows/deploy.yml
Adds CFBundleDocumentTypes and UTExportedTypeDeclarations for model formats and includes Homebrew cask postflight notes plus workflow logic to append an lsregister postflight.
Windows installer & per-user registration
packaging/windows/QtMeshEditor.iss, scripts/register-windows-file-associations.ps1, scripts/update-winget.sh, .github/workflows/deploy.yml
Inno Setup installer script and per-user HKCU registration mappings, PowerShell helper to register Explorer “Open with” without admin rights, WinGet manifest FileExtensions in update-winget.sh, and workflow steps to bundle script, build, and upload installer EXE.
Linux desktop, MIME, and deb packaging
packaging/linux/qtmesheditor.desktop, packaging/linux/qtmesheditor-mimetypes.xml, packaging/linux/DEBIAN-postinst, snap/gui/qtmesheditor.desktop, .github/workflows/deploy.yml
Adds .desktop launcher with Exec=qtmesheditor %F, shared-mime-info XML for model types, Debian postinst to update MIME/desktop DBs, snap desktop metadata changes, and workflow .deb layout and permission wiring.
Verification scripts, WinGet, Homebrew, CI wiring
scripts/verify-file-associations.sh, scripts/update-winget.sh, .github/workflows/deploy.yml, packaging/macos/homebrew-cask-postflight.rb
Adds verification smoke-tests for packaging and source artifacts, integrates execution into the deploy verification job, updates WinGet manifest generator with FileExtensions, and conditionally appends Homebrew postflight logic.
Docs and README
README.md, website/src/DocsApp.jsx
README notes OS double-click/open behavior and portable Windows registration; website adds "Open 3D Files" docs section and nav entry.

Sequence Diagram(s)

sequenceDiagram
  participant User as OS (double-click)
  participant NewProcess as New Process
  participant main_cpp as main.cpp
  participant AppLaunchHandler
  participant QLocalServer
  participant MainWindow

  User->>NewProcess: open file path
  NewProcess->>main_cpp: start with args
  main_cpp->>AppLaunchHandler: collectGuiLaunchPaths(args)
  AppLaunchHandler->>QLocalServer: tryForwardToRunningInstance(paths)
  alt forwarded to running instance
    QLocalServer->>AppLaunchHandler: deliver QStringList
    AppLaunchHandler->>MainWindow: emit filesRequested(paths)
    MainWindow->>MainWindow: openLaunchFiles(paths)
  else start server and continue startup
    AppLaunchHandler->>AppLaunchHandler: startSingleInstanceServer()
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 I nibble bytes and stitch the seams,

plist and .desktop, installer dreams,
A single instance greets each click,
Files hop in — no extra trick.
Hooray — scripts, builds, and docs in beams!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: implementing OS file handlers and launch-with-file functionality across platforms.
Description check ✅ Passed The PR description provides comprehensive technical details organized by platform slices (Qt, macOS, Windows, Linux, CI) and includes test results validating implementation. However, it does not follow the provided repository template structure with Summary/Technical Details sections.
Linked Issues check ✅ Passed The PR fully implements all objectives from epic #664: AppLaunchHandler for Qt [#664], CFBundleDocumentTypes/postflight for macOS [#664], Inno Setup + PowerShell registration for Windows [#664], .desktop + MIME XML + postinst for Linux [#664], and verify-file-associations.sh for CI [#664]. All code changes align with acceptance criteria.
Out of Scope Changes check ✅ Passed All file changes are directly scoped to implementing OS-level file association support as defined in #664. The website documentation, README updates, and CI verification script are supporting changes that enhance the feature delivery; no unrelated refactoring or feature creep is present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/file-associations-664

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 128a5a827e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/main.cpp
Comment on lines +230 to +234
const QStringList launchPaths = AppLaunchHandler::collectGuiLaunchPaths(a.arguments());
AppLaunchHandler launchHandler;
if (!launchPaths.isEmpty() && launchHandler.tryForwardToRunningInstance(launchPaths))
return 0;
launchHandler.startSingleInstanceServer();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Buffer launch requests before the welcome dialog

When the app is started normally and WelcomeDialog::shouldShow() is true, this creates the launch handler and starts the local server before any filesRequested receiver is connected. If the user double-clicks a model (or Finder sends a QFileOpenEvent) while that modal welcome dialog is open, the second instance successfully forwards the path and exits, but the signal is emitted with no MainWindow connected, so the requested file is silently dropped.

Useful? React with 👍 / 👎.

Comment thread packaging/windows/QtMeshEditor.iss Outdated

[Registry]
; Animatable / common interchange formats (Alternate handler)
Root: HKCU; Subkey: "Software\Classes\.fbx"; ValueType: string; ValueName: ""; ValueData: "QtMeshEditor.Model.fbx"; Tasks: fileassoc; Flags: uninsdeletevalue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Register as Open With without replacing defaults

For users who leave the installer’s “Open with handler” task selected, writing the default value under HKCU\Software\Classes\.fbx makes QtMeshEditor the per-user default ProgID for that extension rather than just adding it to Open With; the same pattern is repeated for the other extensions. This can unexpectedly steal existing file associations, and uninstalling with uninsdeletevalue can remove the user's previous default instead of restoring it.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/update-winget.sh (1)

27-31: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast when release download fails before hashing.

Line 27 should use HTTP-fail behavior; otherwise a 404/500 body is hashed and the script emits a valid-looking but wrong SHA256.

Suggested patch
-SHA256=$(curl -sL "${ZIP_URL}" | shasum -a 256 | cut -d' ' -f1 | tr 'a-f' 'A-F')
+SHA256=$(curl -fsSL "${ZIP_URL}" | shasum -a 256 | cut -d' ' -f1 | tr 'a-f' 'A-F')
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/update-winget.sh` around lines 27 - 31, The current SHA256 assignment
pipes the download body (including 404/500 HTML) into shasum; change the
download step to fail fast on HTTP errors by using curl's fail option (or by
checking curl's exit status before computing SHA256) so that "${ZIP_URL}"
returns non-zero on HTTP errors and the script exits early; update the SHA256
assignment and/or add an explicit curl check referencing the ZIP_URL and SHA256
variables so the script prints the existing error message and exits if the
download failed.
🧹 Nitpick comments (1)
.github/workflows/deploy.yml (1)

501-510: ⚡ Quick win

Consider verifying Inno Setup installation before invoking ISCC.

The step installs Inno Setup via Chocolatey but doesn't verify success before running the compiler. If the installation fails silently, line 510 would produce a cryptic "command not found" error.

🛡️ Add installation check
       run: |
         choco install innosetup -y --no-progress
+        $isccPath = "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe"
+        if (-not (Test-Path $isccPath)) {
+          Write-Error "Inno Setup installation failed or ISCC.exe not found at $isccPath"
+          exit 1
+        }
         $version = "${{ github.ref_name }}".TrimStart("v")
         $iss = Get-Content "${{github.workspace}}/packaging/windows/QtMeshEditor.iss" -Raw
         $iss = $iss.Replace("`@PROJECT_VERSION`@", $version)
         Set-Content -Path "${{github.workspace}}/packaging/windows/QtMeshEditor.build.iss" -Value $iss
-        & "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" "${{github.workspace}}/packaging/windows/QtMeshEditor.build.iss"
+        & $isccPath "${{github.workspace}}/packaging/windows/QtMeshEditor.build.iss"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/deploy.yml around lines 501 - 510, The workflow step
installs Inno Setup with "choco install innosetup" but never verifies the
install before calling ISCC.exe; update the step to check the install result
(e.g., inspect $LASTEXITCODE or test the ISCC.exe path at
"${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe") after running choco, log a
clear error via Write-Error if the installer is missing or choco failed, and
exit the script (non-zero) so the job fails fast instead of producing a cryptic
"command not found" when calling ISCC.exe.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/verify-file-associations.sh`:
- Line 12: The verifier uses grep -q "$needle" "$file" which treats $needle as a
regex; change it to use fixed-string matching by calling grep with the
--fixed-strings (or -F) flag and include -- before operands to protect needles
that start with -, e.g. replace the grep invocation that references the
variables needle and file with a fixed-string, quiet grep (e.g. grep -F -q --
"$needle" "$file") so the check is literal and deterministic.

In `@src/AppLaunchHandler.cpp`:
- Around line 176-189: Add a Sentry breadcrumb in
AppLaunchHandler::handleIncomingPaths before emitting filesRequested: when
accepted is not empty call SentryReporter::addBreadcrumb("file.import",
<message>) and include meaningful context (e.g., number of files or the joined
accepted paths) then emit filesRequested(accepted); place the call immediately
before the emit so each user file-open action is tracked.
- Around line 191-202: AppLaunchHandler::eventFilter currently handles macOS
QFileOpenEvent but doesn't record a Sentry breadcrumb; before calling
handleIncomingPaths (and after extracting the absolute path via QFileInfo), add
a Sentry breadcrumb describing the FileOpen action (include event type
"FileOpen" and the file path) so file-open user actions are tracked; ensure the
breadcrumb is added only when path is non-empty and isImportableMeshPath(path)
is true, then proceed to call handleIncomingPaths and return true as before.

In `@website/src/DocsApp.jsx`:
- Around line 217-223: The "Supported extensions" paragraph (h3 with class
s.subsection and following p with class s.para containing multiple <Code>
entries) currently lists many formats but overstates Windows file-association
behavior; update the text to either (A) restrict the listed extensions to only
those registered for double-click on Windows, or (B) relabel the paragraph to
"App import support" and add a new, explicit per-platform subsection (e.g.,
"Windows file associations") that lists the exact extensions registered on
Windows. Adjust the copy under the h3 (and any related <Code> entries)
accordingly so UI truthfully reflects platform-specific registration scope.

---

Outside diff comments:
In `@scripts/update-winget.sh`:
- Around line 27-31: The current SHA256 assignment pipes the download body
(including 404/500 HTML) into shasum; change the download step to fail fast on
HTTP errors by using curl's fail option (or by checking curl's exit status
before computing SHA256) so that "${ZIP_URL}" returns non-zero on HTTP errors
and the script exits early; update the SHA256 assignment and/or add an explicit
curl check referencing the ZIP_URL and SHA256 variables so the script prints the
existing error message and exits if the download failed.

---

Nitpick comments:
In @.github/workflows/deploy.yml:
- Around line 501-510: The workflow step installs Inno Setup with "choco install
innosetup" but never verifies the install before calling ISCC.exe; update the
step to check the install result (e.g., inspect $LASTEXITCODE or test the
ISCC.exe path at "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe") after running
choco, log a clear error via Write-Error if the installer is missing or choco
failed, and exit the script (non-zero) so the job fails fast instead of
producing a cryptic "command not found" when calling ISCC.exe.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1780a39f-3db4-4e26-844a-fd4171a989ac

📥 Commits

Reviewing files that changed from the base of the PR and between ef4c938 and 128a5a8.

📒 Files selected for processing (20)
  • .github/workflows/deploy.yml
  • README.md
  • packaging/linux/DEBIAN-postinst
  • packaging/linux/qtmesheditor-mimetypes.xml
  • packaging/linux/qtmesheditor.desktop
  • packaging/macos/homebrew-cask-postflight.rb
  • packaging/windows/QtMeshEditor.iss
  • scripts/register-windows-file-associations.ps1
  • scripts/update-winget.sh
  • scripts/verify-file-associations.sh
  • snap/gui/qtmesheditor.desktop
  • src/AppLaunchHandler.cpp
  • src/AppLaunchHandler.h
  • src/AppLaunchHandler_test.cpp
  • src/CMakeLists.txt
  • src/Info.plist.in
  • src/main.cpp
  • src/mainwindow.cpp
  • src/mainwindow.h
  • website/src/DocsApp.jsx
👮 Files not reviewed due to content moderation or server errors (7)
  • src/main.cpp
  • src/mainwindow.cpp
  • src/mainwindow.h
  • src/Info.plist.in
  • packaging/macos/homebrew-cask-postflight.rb
  • packaging/windows/QtMeshEditor.iss
  • scripts/register-windows-file-associations.ps1

Comment thread scripts/verify-file-associations.sh Outdated
Comment thread src/AppLaunchHandler.cpp
Comment thread src/AppLaunchHandler.cpp
Comment thread website/src/DocsApp.jsx Outdated
Queue launch paths during the welcome dialog, register Windows handlers
via OpenWithProgids instead of replacing defaults, add Sentry breadcrumbs,
tighten docs to per-platform registration scope, and harden CI/scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/register-windows-file-associations.ps1 (1)

8-15: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Default -BinDir points to the wrong directory in the shipped portable layout.

When this script is bundled under bin/scripts, Line 8 resolves to bin/bin, so Line 13 fails unless users manually pass -BinDir. That breaks the default invocation path for portable usage.

Suggested fix
-param(
-    [string]$BinDir = (Join-Path $PSScriptRoot "..\bin")
-)
+param(
+    [string]$BinDir
+)
+
+if (-not $BinDir) {
+    $portableBin = Join-Path $PSScriptRoot ".."
+    $repoBin     = Join-Path $PSScriptRoot "..\bin"
+    $BinDir = if (Test-Path (Join-Path $portableBin "QtMeshEditor.exe")) { $portableBin } else { $repoBin }
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/register-windows-file-associations.ps1` around lines 8 - 15, The
default $BinDir calculation produces "bin/bin" when the script sits in
bin/scripts; update how $BinDir is derived so it points to the shipped portable
layout's real bin directory: compute $BinDir from the script's parent directory
(use Split-Path $PSScriptRoot -Parent and then Join-Path that parent with "bin")
and add a simple fallback check that if the constructed $exe (Join-Path $BinDir
"QtMeshEditor.exe") doesn't exist, also try the sibling bin under $PSScriptRoot
itself before erroring; keep references to $BinDir, $PSScriptRoot, $exe and the
Test-Path/Write-Error logic but adjust the initial $BinDir assignment and add
the fallback probe.
🧹 Nitpick comments (1)
scripts/register-windows-file-associations.ps1 (1)

33-37: ⚡ Quick win

Align ProgID format with installer to keep one Windows association contract.

Line 33 generates QtMeshEditor.Modelfbx, while the installer uses QtMeshEditor.Model.fbx. Keeping these different can create duplicate handlers between portable and installed flows.

Suggested fix
-    $progId = "QtMeshEditor.Model$($ext.Replace('.', ''))"
+    $progId = "QtMeshEditor.Model.$($ext.TrimStart('.'))"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/register-windows-file-associations.ps1` around lines 33 - 37, The
ProgID construction uses $progId = "QtMeshEditor.Model$($ext.Replace('.', ''))"
which removes the dot and produces "QtMeshEditor.Modelfbx"; change the
assignment to preserve the dot so the ProgID matches the installer
("QtMeshEditor.Model.fbx") — e.g. build $progId from $ext directly or ensure a
leading dot is inserted (use "QtMeshEditor.Model$ext" or
"QtMeshEditor.Model.$($ext.TrimStart('.'))") so $progId aligns with the
installer and prevents duplicate handlers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@scripts/register-windows-file-associations.ps1`:
- Around line 8-15: The default $BinDir calculation produces "bin/bin" when the
script sits in bin/scripts; update how $BinDir is derived so it points to the
shipped portable layout's real bin directory: compute $BinDir from the script's
parent directory (use Split-Path $PSScriptRoot -Parent and then Join-Path that
parent with "bin") and add a simple fallback check that if the constructed $exe
(Join-Path $BinDir "QtMeshEditor.exe") doesn't exist, also try the sibling bin
under $PSScriptRoot itself before erroring; keep references to $BinDir,
$PSScriptRoot, $exe and the Test-Path/Write-Error logic but adjust the initial
$BinDir assignment and add the fallback probe.

---

Nitpick comments:
In `@scripts/register-windows-file-associations.ps1`:
- Around line 33-37: The ProgID construction uses $progId =
"QtMeshEditor.Model$($ext.Replace('.', ''))" which removes the dot and produces
"QtMeshEditor.Modelfbx"; change the assignment to preserve the dot so the ProgID
matches the installer ("QtMeshEditor.Model.fbx") — e.g. build $progId from $ext
directly or ensure a leading dot is inserted (use "QtMeshEditor.Model$ext" or
"QtMeshEditor.Model.$($ext.TrimStart('.'))") so $progId aligns with the
installer and prevents duplicate handlers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eeb4e6f4-e547-4ffe-8754-25bab7c7beec

📥 Commits

Reviewing files that changed from the base of the PR and between 128a5a8 and 6503004.

📒 Files selected for processing (8)
  • .github/workflows/deploy.yml
  • packaging/windows/QtMeshEditor.iss
  • scripts/register-windows-file-associations.ps1
  • scripts/update-winget.sh
  • scripts/verify-file-associations.sh
  • src/AppLaunchHandler.cpp
  • src/main.cpp
  • website/src/DocsApp.jsx
🚧 Files skipped from review as they are similar to previous changes (7)
  • scripts/update-winget.sh
  • scripts/verify-file-associations.sh
  • src/main.cpp
  • website/src/DocsApp.jsx
  • src/AppLaunchHandler.cpp
  • packaging/windows/QtMeshEditor.iss
  • .github/workflows/deploy.yml

Replace the heredoc in the Homebrew cask update step with echo lines so YAML parses correctly, and align the portable registration script with the Inno Setup ProgID format and bin layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
@sonarqubecloud

sonarqubecloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

@fernandotonon
fernandotonon merged commit 4a7d0e5 into master Jun 10, 2026
20 checks passed
@fernandotonon
fernandotonon deleted the feat/file-associations-664 branch June 10, 2026 02:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Epic: FileAssoc — Be the recommended 3D model viewer on macOS, Windows, and Linux

1 participant