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:
parent
939182f391
commit
ad4e4b0a7e
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user