diff --git a/plugins/feature/freqdisplay/freqdisplaygui.cpp b/plugins/feature/freqdisplay/freqdisplaygui.cpp index 05032021f..095877aaa 100644 --- a/plugins/feature/freqdisplay/freqdisplaygui.cpp +++ b/plugins/feature/freqdisplay/freqdisplaygui.cpp @@ -1,6 +1,8 @@ #include #include +#include #include +#include #include "channel/channelwebapiutils.h" #include "gui/buttonswitch.h" @@ -63,7 +65,8 @@ FreqDisplayGUI::FreqDisplayGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, ui(new Ui::FreqDisplayGUI), m_freqDisplay(reinterpret_cast(feature)), m_availableChannelOrFeatureHandler(QStringList(), rxTxChannelKinds), - m_doApplySettings(true) + m_doApplySettings(true), + m_savedMdi(nullptr) { (void) pluginAPI; (void) featureUISet; @@ -370,24 +373,62 @@ void FreqDisplayGUI::applyTransparency() if (m_settings.m_transparentBackground) { - // Clear the entire RollupContents area to alpha=0 so the compositor - // (WA_TranslucentBackground on the window) shows through in the display area. + // Detach from the MDI area so that WA_TranslucentBackground operates at the + // OS compositor level. Inside a QMdiArea the attribute only affects Qt's + // internal backing store, which only passes through for QOpenGLWidget children + // (GPU compositing path) but not for ordinary software-rendered siblings or + // external application windows. + if (!m_savedMdi && mdiArea()) + { + m_savedMdi = mdiArea(); + // Save position in MDI viewport coordinates and convert to screen + // coordinates before the window is reparented. + m_mdiGeometry = geometry(); + const QPoint globalPos = m_savedMdi->viewport()->mapToGlobal(m_mdiGeometry.topLeft()); + // Defer the reparenting to the next event loop iteration so that any + // in-progress paint or layout event completes first. + QTimer::singleShot(0, this, [this, globalPos]() { + if (!m_savedMdi) { return; } + m_savedMdi->removeSubWindow(this); + // Make this a proper top-level frameless overlay window so the OS + // compositor can blend the transparent pixels against everything beneath. + setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + move(globalPos); + resize(m_mdiGeometry.size()); + show(); + }); + } + rollupContents->setTransparentBackground(true); - // Have the settings bar paint its own opaque background over the cleared area - // so that the controls remain fully visible. ui->settingsContainer->setAutoFillBackground(true); } else { - rollupContents->setTransparentBackground(false); - // Restore the settings bar to its default (background painted by RollupContents). - ui->settingsContainer->setAutoFillBackground(false); - } + if (m_savedMdi) + { + QMdiArea* savedMdi = m_savedMdi; + const QRect savedMdiGeometry = m_mdiGeometry; + m_savedMdi = nullptr; + // Convert current screen position back to MDI viewport coordinates so + // the window reappears where the user last placed it. + const QPoint currentGlobalPos = mapToGlobal(QPoint(0, 0)); + const QPoint mdiPos = savedMdi->viewport()->mapFromGlobal(currentGlobalPos); + // Defer re-embedding to the next event loop iteration. + QTimer::singleShot(0, this, [this, savedMdi, mdiPos, savedMdiGeometry]() { + showNormal(); + savedMdi->addSubWindow(this); + show(); + move(mdiPos); + resize(savedMdiGeometry.size()); + }); + } - // Clear any stylesheet overrides left over from earlier implementations. - ui->settingsContainer->setStyleSheet(QString()); - ui->horizontalWidget->setStyleSheet(QString()); - ui->frequencyValue->setStyleSheet(QString()); + rollupContents->setTransparentBackground(false); + ui->settingsContainer->setAutoFillBackground(false); + ui->settingsContainer->setStyleSheet(QString()); + ui->horizontalWidget->setStyleSheet(QString()); + ui->frequencyValue->setStyleSheet(QString()); + } } void FreqDisplayGUI::on_displayMode_currentIndexChanged(int index) diff --git a/plugins/feature/freqdisplay/freqdisplaygui.h b/plugins/feature/freqdisplay/freqdisplaygui.h index cce50d6c7..012af0cde 100644 --- a/plugins/feature/freqdisplay/freqdisplaygui.h +++ b/plugins/feature/freqdisplay/freqdisplaygui.h @@ -18,6 +18,7 @@ class PluginAPI; class FeatureUISet; class FreqDisplay; class Feature; +class QMdiArea; namespace Ui { class FreqDisplayGUI; @@ -54,6 +55,8 @@ private: bool m_doApplySettings; QString m_normalStyleSheet; ///< Stylesheet set by FeatureGUI, saved so it can be restored when transparency is disabled QString m_previousDisplayText; ///< Last text set on frequencyValue, used to detect changes for speech + QMdiArea* m_savedMdi; ///< MDI area saved when window is detached for transparent-background mode + QRect m_mdiGeometry; ///< Window geometry (in MDI viewport coordinates) saved before detaching #ifdef QT_TEXTTOSPEECH_FOUND QTextToSpeech *m_speech = nullptr;