1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-05-14 05:12:09 -04:00

freqdisplay: detach from MDI as floating top-level window for true compositor transparency

Agent-Logs-Url: https://github.com/srcejon/sdrangel/sessions/2a3ba811-8a0c-4e65-b476-8c0523967896

Co-authored-by: srcejon <57259258+srcejon@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-04-18 20:54:57 +00:00 committed by GitHub
parent 939182f391
commit ad4e4b0a7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 13 deletions

View File

@ -1,6 +1,8 @@
#include <QFont>
#include <QLocale>
#include <QMdiArea>
#include <QResizeEvent>
#include <QTimer>
#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<FreqDisplay*>(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)

View File

@ -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;