- Removed native overlay

parent d697940f
......@@ -33,10 +33,11 @@ Successfully replaced the PyQt5 video player implementation with a comprehensive
- **Responsive Design**: Automatic scaling for different resolutions
- **GSAP-ready Structure**: Animation framework integration support
### 3. Legacy Compatibility (mbetterclient/qt_player/overlay_engine.py)
**UPDATED** PyQt5 → PyQt6 imports and constants for compatibility:
- Updated Qt enums to PyQt6 format (Qt.AlignLeft → Qt.AlignmentFlag.AlignLeft)
- Maintained backward compatibility for any remaining legacy code
### 3. Legacy Removal (overlay_engine.py)
**REMOVED** the legacy native overlay engine entirely:
- The native Qt overlay implementation was replaced by the superior QWebEngineView system
- All overlay functionality now uses HTML/CSS/JavaScript templates exclusively
- Removed OverlayEngine and OverlayRenderer classes as they are no longer needed
### 4. Message Bus Integration
**ENHANCED** message handling for complete thread communication:
......@@ -135,7 +136,10 @@ message_bus.publish(overlay_message)
### Modified Files:
- `mbetterclient/qt_player/player.py` - **COMPLETELY REPLACED** with PyQt6 implementation
- `mbetterclient/qt_player/overlay_engine.py` - Updated PyQt5 → PyQt6 imports
- `mbetterclient/qt_player/__init__.py` - Removed legacy overlay engine imports
### Removed Files:
- `mbetterclient/qt_player/overlay_engine.py` - Legacy native overlay implementation removed
### Unchanged Files:
- `mbetterclient/core/application.py` - Works seamlessly with new implementation
......
......@@ -173,11 +173,6 @@ Examples:
help='Disable web dashboard (PyQt interface only)'
)
parser.add_argument(
'--native-overlay',
action='store_true',
help='Use native Qt overlay instead of QWebEngineView (prevents freezing on some systems)'
)
# Screen cast options
parser.add_argument(
......@@ -275,7 +270,6 @@ def main():
settings.debug_overlay = args.debug_overlay
settings.enable_qt = not args.no_qt
settings.enable_web = not args.no_web
settings.qt.use_native_overlay = args.native_overlay
# Timer settings
if args.start_timer is not None:
......
......@@ -922,27 +922,27 @@ class APIClient(ThreadedComponent):
self.message_bus.publish(ready_message)
# Main execution loop
while self.running:
while self.running and not self.shutdown_event.is_set():
try:
# Update heartbeat at the start of each loop
self.heartbeat()
# Process messages
message = self.message_bus.get_message(self.name, timeout=1.0)
if message:
self._process_message(message)
# Update heartbeat before potentially long operations
self.heartbeat()
# Execute scheduled API requests
self._execute_scheduled_requests()
# Update heartbeat after operations
self.heartbeat()
time.sleep(1.0)
except Exception as e:
logger.error(f"APIClient run loop error: {e}")
# Update heartbeat even in error cases
......
......@@ -228,7 +228,6 @@ class QtConfig:
overlay_enabled: bool = True
default_template: str = "news_template"
overlay_opacity: float = 0.9
use_native_overlay: bool = False # Use native Qt widgets instead of QWebEngineView
# Performance settings
hardware_acceleration: bool = True
......
......@@ -133,8 +133,6 @@ class MbetterClientApplication:
stored_settings.enable_web = self.settings.enable_web
stored_settings.enable_screen_cast = self.settings.enable_screen_cast # Preserve screen cast setting
# Preserve command line Qt overlay setting
stored_settings.qt.use_native_overlay = self.settings.qt.use_native_overlay
# Preserve command line debug settings
stored_settings.debug_overlay = self.settings.debug_overlay
......
......@@ -63,7 +63,7 @@ class MatchTimerComponent(ThreadedComponent):
"""Main timer loop"""
logger.info("MatchTimer component started")
while self.running:
while self.running and not self.shutdown_event.is_set():
try:
# Process any pending messages first
message = self.message_bus.get_message(self.name, timeout=0.1)
......
......@@ -183,21 +183,21 @@ class ScreenCastComponent(ThreadedComponent):
self._connect_chromecast()
# Main loop - monitor and restart capture if needed
while self.running:
while self.running and not self.shutdown_event.is_set():
try:
# Process messages
message = self.message_bus.get_message(self.name, timeout=1.0)
if message:
self._process_message(message)
# Check capture health
self._check_capture_health()
# Update heartbeat
self.heartbeat()
time.sleep(1.0)
except Exception as e:
logger.error(f"ScreenCast run loop error: {e}")
time.sleep(1.0)
......
......@@ -233,10 +233,11 @@ class ThreadManager:
def stop_all(self, timeout: float = 10.0) -> bool:
"""Stop all components"""
logger.info("Stopping all components...")
success = True
stop_timeout = timeout / max(len(self.components), 1) # Distribute timeout
# Use at least 8 seconds per component, but distribute total timeout
stop_timeout = max(timeout / max(len(self.components), 1), 8.0)
with self._lock:
for name, component in self.components.items():
try:
......@@ -248,12 +249,12 @@ class ThreadManager:
except Exception as e:
logger.error(f"Exception stopping component {name}: {e}")
success = False
if success:
logger.info("All components stopped successfully")
else:
logger.warning("Some components failed to stop cleanly")
return success
def restart_component(self, name: str, timeout: float = 5.0) -> bool:
......
......@@ -3,13 +3,10 @@ PyQt video player with overlay templates for MbetterClient
"""
from .player import QtVideoPlayer
from .overlay_engine import OverlayEngine, OverlayRenderer
from .templates import TemplateManager, NewsTemplate
__all__ = [
'QtVideoPlayer',
'OverlayEngine',
'OverlayRenderer',
'TemplateManager',
'NewsTemplate'
]
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
......@@ -169,18 +169,18 @@ class TemplateWatcher(ThreadedComponent):
self._scan_existing_templates()
# Message processing loop
while self.running:
while self.running and not self.shutdown_event.is_set():
try:
# Process messages
message = self.message_bus.get_message(self.name, timeout=1.0)
if message:
self._process_message(message)
# Update heartbeat
self.heartbeat()
time.sleep(0.1)
except Exception as e:
logger.error(f"TemplateWatcher run loop error: {e}")
time.sleep(1.0)
......@@ -199,14 +199,23 @@ class TemplateWatcher(ThreadedComponent):
"""Shutdown template watcher"""
try:
logger.info("Shutting down TemplateWatcher...")
if self.observer:
# Unschedule all handlers
for handler in self.event_handlers:
try:
self.observer.unschedule(handler)
except Exception:
pass
self.event_handlers.clear()
self.observer.stop()
self.observer.join()
try:
self.observer.join(timeout=2.0)
except Exception:
pass
self.observer = None
self.event_handler = None
except Exception as e:
logger.error(f"TemplateWatcher shutdown error: {e}")
......
......@@ -432,25 +432,25 @@ class WebDashboard(ThreadedComponent):
server_thread.start()
# Message processing loop
while self.running:
while self.running and not self.shutdown_event.is_set():
try:
# Process messages
message = self.message_bus.get_message(self.name, timeout=1.0)
if message:
self._process_message(message)
# Update heartbeat
self.heartbeat()
time.sleep(0.1)
except Exception as e:
logger.error(f"WebDashboard run loop error: {e}")
time.sleep(1.0)
# Wait for server thread
if server_thread.is_alive():
server_thread.join(timeout=5.0)
# Wait for server thread to finish (with timeout since it's daemon)
if server_thread and server_thread.is_alive():
server_thread.join(timeout=2.0)
except Exception as e:
logger.error(f"WebDashboard run failed: {e}")
......@@ -527,7 +527,8 @@ class WebDashboard(ThreadedComponent):
if self.server:
logger.info("Shutting down HTTP server...")
self.server.shutdown()
logger.info("HTTP server shutdown initiated")
self.server.server_close()
logger.info("HTTP server shutdown completed")
# Note: SocketIO connections will be closed when the server shuts down
# No explicit SocketIO shutdown needed as it's handled by the WSGI server
......
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