Fix Qt player overlay transparency: Allow video to show through WebEngine overlay

- Enhanced QWebEngineView transparency configuration without desktop bleed-through
- Modified overlay HTML structure to remove container wrapper that was blocking video
- Improved overlay positioning as child widget instead of layout widget
- Added explicit transparent background CSS for HTML and body elements
- Fixed overlay container to ensure no background interferes with video display
- Maintained overlay functionality while allowing video content to be visible underneath

This should resolve the issue where videos were playing but hidden behind the overlay widget.
parent bed48471
...@@ -12,11 +12,18 @@ ...@@ -12,11 +12,18 @@
body { body {
font-family: 'Arial', sans-serif; font-family: 'Arial', sans-serif;
background: transparent; background: rgba(0, 0, 0, 0) !important;
overflow: hidden; overflow: hidden;
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
position: relative; position: relative;
/* CRITICAL: Ensure body is completely transparent to allow video through */
background-color: transparent !important;
}
html {
background: transparent !important;
background-color: transparent !important;
} }
/* Debug indicator to verify CSS is loaded */ /* Debug indicator to verify CSS is loaded */
...@@ -38,6 +45,8 @@ ...@@ -38,6 +45,8 @@
height: 100%; height: 100%;
pointer-events: none; pointer-events: none;
z-index: 1000; z-index: 1000;
/* CRITICAL: Ensure container has no background to allow video through */
background: transparent !important;
} }
.title-main { .title-main {
...@@ -248,49 +257,55 @@ ...@@ -248,49 +257,55 @@
</style> </style>
</head> </head>
<body> <body>
<div class="overlay-container"> <!-- CRITICAL: Minimal overlay structure to allow video to show through empty areas -->
<div class="logo" id="logo">
<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAiIGhlaWdodD0iODAiIHZpZXdCb3g9IjAgMCA4MCA4MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjgwIiBoZWlnaHQ9IjgwIiByeD0iMTAiIGZpbGw9IiNkYzM1NDUiLz4KPHRleHQgeD0iNDAiIHk9IjQ1IiBmb250LWZhbWlseT0iQXJpYWwsIHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMjQiIGZvbnQtd2VpZ2h0PSJib2xkIiBmaWxsPSJ3aGl0ZSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZHk9Ii4zNWVtIj5NPC90ZXh0Pgo8L3N2Zz4K" alt="MbetterClient Logo" onerror="this.style.display='none'"> <!-- Logo - positioned but with transparent background -->
<div class="logo" id="logo">
<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAiIGhlaWdodD0iODAiIHZpZXdCb3g9IjAgMCA4MCA4MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjgwIiBoZWlnaHQ9IjgwIiByeD0iMTAiIGZpbGw9IiNkYzM1NDUiLz4KPHRleHQgeD0iNDAiIHk9IjQ1IiBmb250LWZhbWlseT0iQXJpYWwsIHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMjQiIGZvbnQtd2VpZ2h0PSJib2xkIiBmaWxsPSJ3aGl0ZSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZHk9Ii4zNWVtIj5NPC90ZXh0Pgo8L3N2Zz4K" alt="MbetterClient Logo" onerror="this.style.display='none'">
</div>
<!-- Title - only shows when needed, transparent background -->
<div class="title-main" id="titleMain">
MbetterClient Video Player
</div>
<!-- Subtitle - only shows when needed, transparent background -->
<div class="title-subtitle" id="titleSubtitle">
Ready for Content
</div>
<!-- News ticker - positioned at bottom -->
<div class="news-ticker" id="newsTicker">
<div class="ticker-text" id="tickerText">
Welcome to MbetterClient • Professional Video Overlay System • Real-time Updates • Hardware Accelerated Playback
</div> </div>
</div>
<div class="title-main" id="titleMain">
MbetterClient Video Player <!-- Stats panel - positioned at side -->
<div class="stats-panel" id="statsPanel" style="display: none;">
<div class="stats-item">
<span>Resolution:</span>
<span id="resolution">1920x1080</span>
</div> </div>
<div class="stats-item">
<div class="title-subtitle" id="titleSubtitle"> <span>Bitrate:</span>
Ready for Content <span id="bitrate">5.2 Mbps</span>
</div> </div>
<div class="stats-item">
<span>Codec:</span>
<div class="news-ticker" id="newsTicker"> <span id="codec">H.264</span>
<div class="ticker-text" id="tickerText">
Welcome to MbetterClient • Professional Video Overlay System • Real-time Updates • Hardware Accelerated Playback
</div>
</div> </div>
<div class="stats-item">
<div class="stats-panel" id="statsPanel" style="display: none;"> <span>FPS:</span>
<div class="stats-item"> <span id="fps">30.0</span>
<span>Resolution:</span>
<span id="resolution">1920x1080</span>
</div>
<div class="stats-item">
<span>Bitrate:</span>
<span id="bitrate">5.2 Mbps</span>
</div>
<div class="stats-item">
<span>Codec:</span>
<span id="codec">H.264</span>
</div>
<div class="stats-item">
<span>FPS:</span>
<span id="fps">30.0</span>
</div>
</div> </div>
<canvas class="canvas-overlay" id="canvasOverlay"></canvas>
<div class="progress-bar" id="progressBar" style="width: 0%;"></div>
</div> </div>
<!-- Canvas for custom animations - transparent background -->
<canvas class="canvas-overlay" id="canvasOverlay"></canvas>
<!-- Progress bar at bottom -->
<div class="progress-bar" id="progressBar" style="width: 0%;"></div>
<script src="qrc:///qtwebchannel/qwebchannel.js"></script> <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script> <script>
......
...@@ -153,18 +153,20 @@ class OverlayWebView(QWebEngineView): ...@@ -153,18 +153,20 @@ class OverlayWebView(QWebEngineView):
logger.info("OverlayWebView initialized") logger.info("OverlayWebView initialized")
def setup_web_view(self): def setup_web_view(self):
"""Setup web view as embedded overlay with CSS transparency""" """Setup web view as embedded overlay with pointer-event transparency"""
logger.debug("OverlayWebView.setup_web_view() - Starting embedded setup") logger.debug("OverlayWebView.setup_web_view() - Starting embedded setup")
# Use CSS transparency instead of widget transparency to prevent desktop bleed-through
logger.debug("Using CSS transparency for embedded overlay")
# Configure page settings for proper rendering with transparent background # Configure page settings for proper rendering with transparent background
page = self.page() page = self.page()
logger.debug("Setting page background to transparent (0,0,0,0)") logger.debug("Setting page background to transparent (0,0,0,0)")
page.setBackgroundColor(QColor(0, 0, 0, 0)) # Transparent page background page.setBackgroundColor(QColor(0, 0, 0, 0)) # Transparent page background
# Set QWebEngineView style for embedded use - no widget transparency # CRITICAL: Use pointer-events approach instead of widget transparency to avoid desktop bleed
self.setAttribute(Qt.WidgetAttribute.WA_OpaquePaintEvent, False)
self.setAttribute(Qt.WidgetAttribute.WA_NoSystemBackground, True)
# DO NOT use WA_TranslucentBackground - it causes desktop transparency issues
# Style for overlay that allows video to show through background areas
self.setStyleSheet(""" self.setStyleSheet("""
QWebEngineView { QWebEngineView {
background: transparent; background: transparent;
...@@ -172,9 +174,6 @@ class OverlayWebView(QWebEngineView): ...@@ -172,9 +174,6 @@ class OverlayWebView(QWebEngineView):
} }
""") """)
# Ensure overlay is positioned correctly as child widget
self.setAttribute(Qt.WidgetAttribute.WA_OpaquePaintEvent, False)
logger.debug("OverlayWebView embedded setup completed") logger.debug("OverlayWebView embedded setup completed")
# Setup WebChannel # Setup WebChannel
...@@ -471,15 +470,14 @@ class VideoWidget(QWidget): ...@@ -471,15 +470,14 @@ class VideoWidget(QWidget):
layout = QVBoxLayout(self) layout = QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0) layout.setSpacing(0)
# LAYER 1: Video widget as base layer # LAYER 1: Video widget as base layer - this shows the actual video
# Shows solid black when no video, shows video content when playing
self.video_widget = QVideoWidget() self.video_widget = QVideoWidget()
self.video_widget.setStyleSheet("QVideoWidget { background-color: black; }") self.video_widget.setStyleSheet("QVideoWidget { background-color: black; }")
self.video_widget.setAttribute(Qt.WidgetAttribute.WA_OpaquePaintEvent, True) self.video_widget.setAttribute(Qt.WidgetAttribute.WA_OpaquePaintEvent, True)
layout.addWidget(self.video_widget) layout.addWidget(self.video_widget)
# LAYER 2: Overlay - either native Qt or QWebEngineView # LAYER 2: Overlay as child widget positioned on top (NOT in layout)
if self.use_native_overlay: if self.use_native_overlay:
self.overlay_view = NativeOverlayWidget(self) self.overlay_view = NativeOverlayWidget(self)
logger.debug("VideoWidget using native Qt overlay") logger.debug("VideoWidget using native Qt overlay")
...@@ -487,6 +485,11 @@ class VideoWidget(QWidget): ...@@ -487,6 +485,11 @@ class VideoWidget(QWidget):
self.overlay_view = OverlayWebView(self) self.overlay_view = OverlayWebView(self)
logger.debug("VideoWidget using QWebEngineView overlay") logger.debug("VideoWidget using QWebEngineView overlay")
# CRITICAL: Don't add overlay to layout - position it manually as floating child
# This allows the video widget to render underneath
self.overlay_view.setParent(self)
self.overlay_view.raise_() # Ensure overlay is on top
logger.debug(f"VideoWidget overlay setup completed (native={self.use_native_overlay})") logger.debug(f"VideoWidget overlay setup completed (native={self.use_native_overlay})")
def resizeEvent(self, event): def resizeEvent(self, event):
...@@ -497,8 +500,10 @@ class VideoWidget(QWidget): ...@@ -497,8 +500,10 @@ class VideoWidget(QWidget):
# Position overlay to match the video widget exactly # Position overlay to match the video widget exactly
video_geometry = self.video_widget.geometry() video_geometry = self.video_widget.geometry()
self.overlay_view.setGeometry(video_geometry) self.overlay_view.setGeometry(video_geometry)
self.overlay_view.raise_() # Bring overlay to front
logger.debug(f"Overlay repositioned to {video_geometry}") # Position overlay to exactly cover video widget
self.overlay_view.raise_() # Ensure overlay stays on top
logger.debug(f"Overlay repositioned: {video_geometry}")
def get_video_widget(self) -> QVideoWidget: def get_video_widget(self) -> QVideoWidget:
"""Get the video widget for media player""" """Get the video widget for media player"""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment