Skip to content

fix: parent background image dialog to top-level window, use Qt dialog#2865

Open
NF0T wants to merge 1 commit into
aethersdr:mainfrom
NF0T:fix/background-image-dialog-hang
Open

fix: parent background image dialog to top-level window, use Qt dialog#2865
NF0T wants to merge 1 commit into
aethersdr:mainfrom
NF0T:fix/background-image-dialog-hang

Conversation

@NF0T
Copy link
Copy Markdown
Collaborator

@NF0T NF0T commented May 18, 2026

Summary

Fixes #723.

Setting a background image via Display → Background → "Choose…" caused AetherSDR to become unresponsive on Linux, requiring a force-kill. The application appeared frozen with no dialog visible.

Root cause

Two compounding problems in the single `QFileDialog::getOpenFileName` call at `MainWindow.cpp:10800`:

1. Wrong parent widget. The dialog was parented to `sw` — the `SpectrumWidget`, which is a `QRhiWidget` backed by a native hardware render surface. On X11/Wayland the window manager cannot reliably establish a transient-for relationship between a native modal dialog and a QRhi surface. The modal grab fires but the dialog cannot receive focus or complete initialization, wedging the GUI thread.

2. Native dialog backend. Without `DontUseNativeDialog`, Qt routes through the platform portal (xdg-desktop-portal, GTK, or KDE depending on desktop environment). On Linux Mint Cinnamon and other environments where the portal is absent or misconfigured, the blocking `getOpenFileName` call never returns.

Either problem alone is sufficient to reproduce the hang; together they make it near-certain on affected Linux desktops.

Fix

Two argument changes to the one affected call site:

  • `sw` → `sw->window()`: parents the dialog to the top-level `QMainWindow`, which has a valid native window handle the WM can use for transient-for.
  • Add `QFileDialog::DontUseNativeDialog`: forces Qt's own cross-platform file dialog, bypassing the portal/GTK/KDE backend entirely.

Applied unconditionally — no platform guards needed. The Qt dialog renders correctly on all three platforms; the visual difference from the system-native dialog on macOS/Windows is cosmetic only.

Other `getOpenFileName` call sites — not affected

All other file dialog calls in the codebase (`RadioSetupDialog`, `DvkPanel`, `MemoryDialog`, `DxClusterDialog`, `ProfileImportExportDialog`) parent to `this` (a standard QDialog or QWidget), not a QRhi surface. They are unaffected by this root cause and require no changes.

Out of scope

`SpectrumWidget::setBackgroundImage` decodes the image synchronously on the GUI thread (`QImage(path)`). For very large files this could produce a brief stall. This is a pre-existing minor concern, not the cause of the hang reported in #723, and is tracked separately.

Test plan

  • On a Linux desktop (Cinnamon, MATE, or XFCE): Display → Background → "Choose…" — confirm dialog opens without freezing
  • Select a valid image — confirm it appears as the spectrum background
  • Cancel the dialog — confirm the application remains responsive
  • Confirm behavior unchanged on macOS and Windows (dialog opens, image selection works)
  • Confirm the "Clear" button still resets to the default background

🤖 Generated with Claude Code

The "Choose Background Image" file dialog was parented to the
SpectrumWidget (a QRhiWidget with a native hardware render surface).
On X11/Wayland the window manager cannot reliably establish a
transient-for relationship with a QRhi surface, causing the modal
grab to wedge the GUI thread and the application to become
unresponsive. The native portal/GTK/KDE dialog backend compounds
this on Linux Mint and similar desktops where the portal is absent
or misconfigured — the blocking call never returns.

Fix: parent the dialog to sw->window() (the top-level QMainWindow)
so the WM gets a valid transient-for target, and pass
DontUseNativeDialog to bypass the portal/backend entirely.
Both changes are independently sufficient; together they cover the
full Linux DE matrix.

No other getOpenFileName call sites are affected — all parent to
ordinary QWidget/QDialog instances, not QRhi surfaces.

Fixes aethersdr#723.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@NF0T NF0T requested a review from ten9876 as a code owner May 18, 2026 23:35
Copy link
Copy Markdown
Contributor

@aethersdr-agent aethersdr-agent Bot left a comment

Choose a reason for hiding this comment

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

Looks good. Thanks @NF0T — clear root cause writeup and a minimal, targeted fix.

Verified the analysis:

  • SpectrumWidget is QRhiWidget when SPECTRUM_BASE_CLASS is the GPU path (src/gui/SpectrumWidget.h:22), confirming the transient-for problem.
  • All other QFileDialog::getOpenFileName call sites (RadioSetupDialog, DvkPanel, MemoryDialog, DxClusterDialog, ProfileImportExportDialog, AetherialAudioStrip) parent to this on standard QWidget/QDialog subclasses, so they're unaffected by the same root cause.

Two argument changes, no new failure modes — sw->window() is non-null for any wired panadapter (it's already been added to the main window tree by the time wirePanadapter runs), and DontUseNativeDialog is a documented Qt flag with no platform guards needed.

The out-of-scope note about synchronous QImage decode on the GUI thread is fair to defer — that's a separate concern from the hang in #723.

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.

Setting Background Image causes AetherSDR to become unresponsive

1 participant