Title: Windows Aero Snap (drag-to-top maximize) does not work on Windows
What happened?
When dragging the AetherSDR application window to the top edge of the monitor on Windows, the OS-native Aero Snap gesture does not trigger. Normally, dragging a window to the top of the screen causes Windows to display a snap preview overlay and, on release, maximize the window to fill the screen. Neither the preview overlay nor the maximize action occurs. The window simply returns to its previous size and position when released.
This affects both single-monitor and multi-monitor setups. Other standard snap gestures (e.g., dragging to left/right edges for side-by-side snapping) may also be affected, but the primary symptom is the failure of the drag-to-top-to-maximize gesture.
What did you expect?
Dragging the AetherSDR window title bar to the top of the monitor should trigger the standard Windows Aero Snap behavior: a translucent maximize preview should appear while dragging, and releasing the window at the top edge should cause it to maximize to fill the available screen area — identical to the behavior of any standard Win32 or WPF application (including SmartSDR).
Double-clicking the title bar to maximize and using the maximize button in the window chrome should be unaffected (these are separate code paths), but Aero Snap via dragging specifically does not function.
Steps to reproduce
- Launch AetherSDR 0.9.0 on Windows (connection to radio is not required to reproduce).
- Ensure the AetherSDR window is in a restored (non-maximized) state.
- Click and hold the window title bar.
- Drag the window upward toward the top edge of the primary monitor.
- Observe: no Aero Snap preview overlay appears.
- Release the mouse button at the top edge of the screen.
- Observe: the window does not maximize; it returns to its previous position and size.
Radio model & firmware
- Radio: FLEX-6600
- Firmware: 4.1.5.39794
OS & version
AetherSDR & Qt versions
- AetherSDR: 0.9.0
- Qt: 6.7.3
Developer Notes
Likely root cause
Windows Aero Snap is a DWM (Desktop Window Manager) feature that depends on the window receiving and correctly handling the WM_NCHITTEST message. Qt intercepts WM_NCHITTEST via its native event filter to implement its own hit-testing (for resize handles, drag areas, etc.). If AetherSDR sets any of the following, Aero Snap will silently break:
Qt::FramelessWindowHint — removes the native title bar and borders entirely. DWM cannot snap a frameless window because there is no native HTCAPTION region for the drag to register against.
Qt::CustomizeWindowHint without Qt::WindowTitleHint — similarly strips DWM's awareness of the title bar drag region.
- A custom
nativeEventFilter or winEvent override that swallows WM_NCHITTEST before returning HTCAPTION — DWM never sees the message and cannot initiate snap.
- An
eventFilter on the QApplication or MainWindow that consumes or suppresses mouse move/button events during a title bar drag.
Files and functions to investigate
| File |
What to check |
src/gui/MainWindow.cpp / MainWindow.h |
Window flags passed to setWindowFlags() or the QMainWindow constructor; any nativeEvent() override; any eventFilter() override (already referenced in CLAUDE.md for the +PAN button) |
src/main.cpp |
Any setAttribute() calls on QApplication or the MainWindow instance before show(); DPI scaling attributes that may affect window style |
src/gui/MainWindow.cpp → MainWindow::eventFilter() |
Already known to intercept events (used by the disabled +PAN button). Verify it is not consuming QEvent::MouseMove or native window drag events at the application level. |
Specific things to check in MainWindow
// Does the constructor or any setup method call any of these?
setWindowFlags(Qt::FramelessWindowHint); // breaks Aero Snap
setWindowFlags(Qt::CustomizeWindowHint); // may break Aero Snap
setAttribute(Qt::WA_TranslucentBackground); // often paired with FramelessWindowHint
Also check whether MainWindow overrides nativeEvent() and, if so, whether the WM_NCHITTEST message is being consumed or returning a non-HTCAPTION value for the title bar region.
Likely fix
If Qt::FramelessWindowHint is set (e.g. for a custom dark title bar to match the #0f0f1a theme), the fix is to extend the DWM frame into the client area so that DWM regains snap awareness, while keeping the custom visual appearance:
// In MainWindow constructor, after show(), on Windows only:
#ifdef Q_OS_WIN
#include <dwmapi.h>
MARGINS margins = {1, 1, 1, 1};
DwmExtendFrameIntoClientArea(reinterpret_cast<HWND>(winId()), &margins);
#endif
And in nativeEvent(), return HTCAPTION for the title bar drag region so DWM can intercept the drag for snapping:
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, qintptr *result) {
MSG *msg = static_cast<MSG *>(message);
if (msg->message == WM_NCHITTEST) {
// ... custom hit testing ...
// Ensure the title bar area returns HTCAPTION so Aero Snap works
*result = HTCAPTION;
return true;
}
return QMainWindow::nativeEvent(eventType, message, result);
}
If the window is not frameless and Aero Snap is still broken, the bug is more likely in MainWindow::eventFilter() consuming mouse events — audit every return true path in that function to ensure title-bar drag events are not being swallowed.
Logging to enable
No existing logging categories in Help → Support are directly relevant to this issue (it is a pure Windows window-manager/Qt interaction, not a radio protocol or audio path issue). To diagnose:
- Build a debug build (
CMAKE_BUILD_TYPE=Debug) and run under Qt Creator or with QT_LOGGING_RULES="qt.qpa.window=true" set in the environment to see Qt's native window event handling.
- On Windows, use Spy++ (included with Visual Studio) to monitor
WM_NCHITTEST messages on the AetherSDR HWND and confirm whether HTCAPTION is being returned for the title bar area.
- Check the window's extended styles with Spy++:
WS_EX_LAYERED combined with WS_EX_TRANSPARENT will also break Aero Snap.
Note on AppSettings / window geometry
AetherSDR persists window geometry (Persistent window geometry and display settings — implemented per CLAUDE.md). If the window is being restored to a size/position that confuses DWM on startup, that could be a secondary contributing factor. Clearing the saved geometry from ~/.config/AetherSDR/AetherSDR.settings (or the Windows equivalent) and retesting with a fresh window state is a useful first diagnostic step.
Title: Windows Aero Snap (drag-to-top maximize) does not work on Windows
What happened?
When dragging the AetherSDR application window to the top edge of the monitor on Windows, the OS-native Aero Snap gesture does not trigger. Normally, dragging a window to the top of the screen causes Windows to display a snap preview overlay and, on release, maximize the window to fill the screen. Neither the preview overlay nor the maximize action occurs. The window simply returns to its previous size and position when released.
This affects both single-monitor and multi-monitor setups. Other standard snap gestures (e.g., dragging to left/right edges for side-by-side snapping) may also be affected, but the primary symptom is the failure of the drag-to-top-to-maximize gesture.
What did you expect?
Dragging the AetherSDR window title bar to the top of the monitor should trigger the standard Windows Aero Snap behavior: a translucent maximize preview should appear while dragging, and releasing the window at the top edge should cause it to maximize to fill the available screen area — identical to the behavior of any standard Win32 or WPF application (including SmartSDR).
Double-clicking the title bar to maximize and using the maximize button in the window chrome should be unaffected (these are separate code paths), but Aero Snap via dragging specifically does not function.
Steps to reproduce
Radio model & firmware
OS & version
AetherSDR & Qt versions
Developer Notes
Likely root cause
Windows Aero Snap is a DWM (Desktop Window Manager) feature that depends on the window receiving and correctly handling the
WM_NCHITTESTmessage. Qt interceptsWM_NCHITTESTvia its native event filter to implement its own hit-testing (for resize handles, drag areas, etc.). If AetherSDR sets any of the following, Aero Snap will silently break:Qt::FramelessWindowHint— removes the native title bar and borders entirely. DWM cannot snap a frameless window because there is no nativeHTCAPTIONregion for the drag to register against.Qt::CustomizeWindowHintwithoutQt::WindowTitleHint— similarly strips DWM's awareness of the title bar drag region.nativeEventFilterorwinEventoverride that swallowsWM_NCHITTESTbefore returningHTCAPTION— DWM never sees the message and cannot initiate snap.eventFilteron theQApplicationorMainWindowthat consumes or suppresses mouse move/button events during a title bar drag.Files and functions to investigate
src/gui/MainWindow.cpp/MainWindow.hsetWindowFlags()or theQMainWindowconstructor; anynativeEvent()override; anyeventFilter()override (already referenced in CLAUDE.md for the +PAN button)src/main.cppsetAttribute()calls onQApplicationor theMainWindowinstance beforeshow(); DPI scaling attributes that may affect window stylesrc/gui/MainWindow.cpp→MainWindow::eventFilter()QEvent::MouseMoveor native window drag events at the application level.Specific things to check in
MainWindowAlso check whether
MainWindowoverridesnativeEvent()and, if so, whether theWM_NCHITTESTmessage is being consumed or returning a non-HTCAPTIONvalue for the title bar region.Likely fix
If
Qt::FramelessWindowHintis set (e.g. for a custom dark title bar to match the#0f0f1atheme), the fix is to extend the DWM frame into the client area so that DWM regains snap awareness, while keeping the custom visual appearance:And in
nativeEvent(), returnHTCAPTIONfor the title bar drag region so DWM can intercept the drag for snapping:If the window is not frameless and Aero Snap is still broken, the bug is more likely in
MainWindow::eventFilter()consuming mouse events — audit everyreturn truepath in that function to ensure title-bar drag events are not being swallowed.Logging to enable
No existing logging categories in Help → Support are directly relevant to this issue (it is a pure Windows window-manager/Qt interaction, not a radio protocol or audio path issue). To diagnose:
CMAKE_BUILD_TYPE=Debug) and run under Qt Creator or withQT_LOGGING_RULES="qt.qpa.window=true"set in the environment to see Qt's native window event handling.WM_NCHITTESTmessages on the AetherSDRHWNDand confirm whetherHTCAPTIONis being returned for the title bar area.WS_EX_LAYEREDcombined withWS_EX_TRANSPARENTwill also break Aero Snap.Note on
AppSettings/ window geometryAetherSDR persists window geometry (
Persistent window geometry and display settings— implemented per CLAUDE.md). If the window is being restored to a size/position that confuses DWM on startup, that could be a secondary contributing factor. Clearing the saved geometry from~/.config/AetherSDR/AetherSDR.settings(or the Windows equivalent) and retesting with a fresh window state is a useful first diagnostic step.