| 359 | } |
| 360 | |
| 361 | bool MainWindow::eventFilter(QObject* obj, QEvent* event) |
| 362 | { |
| 363 | if (obj == qApp && event->type() == QEvent::Quit) { |
| 364 | if (!m_shuttingDown) { |
| 365 | if (m_panStack) { |
| 366 | m_panStack->setShuttingDown(true); |
| 367 | } |
| 368 | QTimer::singleShot(0, this, [this]() { close(); }); |
| 369 | return true; |
| 370 | } |
| 371 | } |
| 372 | |
| 373 | // Belt-and-suspenders for the deactivation fail-safe (#3888, Principle VI): |
| 374 | // on macOS the per-window QEvent::ActivationChange can be unreliable when |
| 375 | // the whole app is backgrounded, so also unkey any held momentary key when |
| 376 | // the application leaves the active state. Do not consume the event. |
| 377 | if (obj == qApp && event->type() == QEvent::ApplicationStateChange) { |
| 378 | auto* stateEvent = static_cast<QApplicationStateChangeEvent*>(event); |
| 379 | if (stateEvent->applicationState() != Qt::ApplicationActive) |
| 380 | failSafeMomentaryKeyingToRx("app-deactivate"); |
| 381 | } |
| 382 | |
| 383 | if (auto* slider = qobject_cast<QAbstractSlider*>(obj)) { |
| 384 | if (event->type() == QEvent::MouseButtonPress |
| 385 | || event->type() == QEvent::MouseButtonDblClick) { |
| 386 | beginSliderShortcutLease(slider); |
| 387 | } else if (event->type() == QEvent::MouseButtonRelease |
| 388 | && m_sliderShortcutLease.data() == slider) { |
| 389 | renewSliderShortcutLease(); |
| 390 | } |
| 391 | } else if (auto* meter = qobject_cast<AetherSDR::MeterSlider*>(obj)) { |
| 392 | // MeterSlider (TCI/DAX gain) gets the same lease so a mouse drag hands |
| 393 | // off to keyboard nudges, then global shortcuts resume after a beat. |
| 394 | if (event->type() == QEvent::MouseButtonPress |
| 395 | || event->type() == QEvent::MouseButtonDblClick) { |
| 396 | beginSliderShortcutLease(meter); |
| 397 | } else if (event->type() == QEvent::MouseButtonRelease |
| 398 | && m_sliderShortcutLease.data() == meter) { |
| 399 | renewSliderShortcutLease(); |
| 400 | } |
| 401 | } |
| 402 | |
| 403 | // Applet-panel floating window — save geometry on move/resize, and |
| 404 | // dock back on close so the menu action stays in sync. |
| 405 | if (obj == m_appletPanelFloatWindow) { |
| 406 | if (event->type() == QEvent::Move || event->type() == QEvent::Resize) { |
| 407 | AppSettings::instance().setValue( |
| 408 | "AppletPanelFloatGeometry", |
| 409 | m_appletPanelFloatWindow->saveGeometry().toBase64()); |
| 410 | } else if (event->type() == QEvent::Close) { |
| 411 | // Distinguish user-initiated close from app shutdown. |
| 412 | // During shutdown, leave AppletPanelFloating=True so the |
| 413 | // next launch re-opens the panel floating — the user |
| 414 | // didn't "dock it back", the whole app is exiting. |
| 415 | if (m_shuttingDown) { |
| 416 | AppSettings::instance().setValue( |
| 417 | "AppletPanelFloatGeometry", |
| 418 | m_appletPanelFloatWindow->saveGeometry().toBase64()); |
nothing calls this directly
no test coverage detected