Skip to main content

AcrylicEffect - Complete Documentation

Overview

info

Cross-Platform Fluent Design: AcrylicEffect brings Windows 11-style frosted glass transparency to Qt applications across all platforms, with intelligent fallbacks for Wayland, X11, Windows, and macOS.

AcrylicEffect is a comprehensive implementation of acrylic blur effects with full cross-platform compatibility. It provides realistic frosted glass transparency with automatic platform detection and appropriate fallback mechanisms for each environment.


Features

success

Professional & Robust: Production-ready acrylic effects with intelligent platform detection, automatic fallbacks, and consistent performance across all operating systems.

  • Multi-Platform Support: Works on Wayland, X11, Windows, macOS with appropriate methods
  • Platform Detection: Automatic detection of display server and OS
  • Intelligent Fallbacks: Graceful degradation when screen grabbing is restricted
  • Realistic Acrylic Material: Multi-layer composition (blur + tint + luminosity + noise)
  • Performance Optimized: Efficient algorithms with scipy/PIL fallbacks
  • Multi-Monitor Aware: Proper handling across multiple displays
  • Dynamic Adaptation: Adjusts behavior based on platform capabilities
  • Robust Error Handling: Comprehensive fallback mechanisms

Installation

warning

Platform Considerations: Install scipy for optimal blur quality, but basic functionality works with PIL fallback. Some platforms (Wayland) have security restrictions that limit screen grabbing.

# Required
pip install QT-PyQt-PySide-Custom-Widgets

# Optional for better blur quality
pip install scipy numpy

# For color analysis
pip install colorthief pillow

Platform-Specific Behavior

Linux (Wayland)

  • Screen Grabbing: Restricted by security policies
  • Fallback: Uses widget-based grabs or creates gradient backgrounds
  • Performance: Excellent with fallback methods
  • Recommendation: Use provided acrylic fallbacks or gradient backgrounds

Linux (X11)

  • Screen Grabbing: Full support
  • Fallback: Full screen capture available
  • Performance: Native screen blurring
  • Recommendation: All features available

Windows

  • Screen Grabbing: Full support
  • Fallback: Standard methods work reliably
  • Performance: Native screen blurring
  • Recommendation: All features available

macOS

  • Screen Grabbing: Limited support via Quartz
  • Fallback: Widget-based grabs or acrylic fallbacks
  • Performance: Good with fallback methods
  • Recommendation: May need fallback configuration

Basic Usage

Simple Cross-Platform Example

tip

Quick Start: This basic example works across all platforms with automatic platform detection and appropriate fallbacks.

from Custom_Widgets.AcrylicEffect import AcrylicEffect
from qtpy.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel
from qtpy.QtCore import Qt, QTimer

class MainWindow(QMainWindow):
def __init__(self):
super().__init__()

# Create central widget
central = QWidget()
self.setCentralWidget(central)
layout = QVBoxLayout(central)

# Add content
label = QLabel("Cross-Platform Acrylic Demo")
label.setAlignment(Qt.AlignCenter)
label.setStyleSheet("font-size: 24px; color: white; padding: 20px;")
layout.addWidget(label)

# Add platform info label
self.platform_label = QLabel()
self.platform_label.setAlignment(Qt.AlignCenter)
self.platform_label.setStyleSheet("color: #aaa; padding: 10px;")
layout.addWidget(self.platform_label)

# Apply acrylic effect
self.acrylic = AcrylicEffect(
widget=central,
blurRadius=15,
tintColor=QColor(242, 242, 242, 150),
luminosityColor=QColor(255, 255, 255, 10),
noiseOpacity=0.03
)
self.acrylic.applyToWidget()

# Get platform info
platform_info = self.acrylic.getPlatformInfo()
self.platform_label.setText(
f"Platform: {platform_info['system'].upper()} | "
f"Display: {platform_info['display_server'].upper()} | "
f"Mode: {'Fallback' if self.acrylic.isUsingFallback() else 'Native'}"
)

# Grab background after window is shown
QTimer.singleShot(100, self.setup_background)

def setup_background(self):
"""Setup acrylic background after window is visible"""
self.acrylic.grabFromScreen()

# Check if using fallback
if self.acrylic.isUsingFallback():
self.platform_label.setText(
self.platform_label.text() + " (Using Acrylic Fallback)"
)

app = QApplication([])
window = MainWindow()
window.resize(600, 400)
window.setWindowTitle("Cross-Platform Acrylic")
window.show()
app.exec_()

Platform-Aware Setup

from Custom_Widgets.AcrylicEffect import AcrylicEffect, PlatformDetector

# Check platform before setup
platform_info = PlatformDetector.detect_platform()

if platform_info['is_wayland']:
print("Running on Wayland - using acrylic fallbacks")
# Configure for Wayland compatibility
blur_radius = 10 # Lower blur for performance
use_fallback_colors = True
elif platform_info['is_x11']:
print("Running on X11 - full screen blur available")
blur_radius = 20 # Higher blur quality
use_fallback_colors = False
elif platform_info['is_windows']:
print("Running on Windows - full features available")
blur_radius = 25
use_fallback_colors = False
elif platform_info['is_macos']:
print("Running on macOS - limited screen grabbing")
blur_radius = 15
use_fallback_colors = True

# Create acrylic effect with platform-appropriate settings
acrylic = AcrylicEffect(
widget=my_widget,
blurRadius=blur_radius,
tintColor=QColor(242, 242, 242, 150),
luminosityColor=QColor(255, 255, 255, 10),
noiseOpacity=0.03
)
acrylic.applyToWidget()

Class Reference

AcrylicEffect

info

Smart Platform Detection: The AcrylicEffect class automatically detects your platform and chooses the appropriate rendering method, providing consistent results across all operating systems.

Main class for applying cross-platform acrylic effects to widgets.

Constructor

AcrylicEffect(
widget: QWidget,
blurRadius: int = 15,
tintColor: QColor = QColor(242, 242, 242, 150),
luminosityColor: QColor = QColor(255, 255, 255, 10),
noiseOpacity: float = 0.03
)

Parameters:

  • widget: Target widget to apply the effect to
  • blurRadius: Gaussian blur radius (5-30 typical, adjust per platform)
  • tintColor: Base tint color with alpha
  • luminosityColor: Luminosity layer color
  • noiseOpacity: Noise texture opacity (0.0-1.0)

PlatformDetector

warning

Essential for Debugging: Use PlatformDetector to understand your runtime environment and troubleshoot platform-specific issues.

Static utility class for platform and display server detection.

# Detect current platform
info = PlatformDetector.detect_platform()
print(f"System: {info['system']}")
print(f"Display Server: {info['display_server']}")
print(f"Is Wayland: {info['is_wayland']}")
print(f"Is X11: {info['is_x11']}")
print(f"Is Windows: {info['is_windows']}")
print(f"Is macOS: {info['is_macos']}")

GaussianBlurUtils

tip

Performance Across Platforms: The blur utility automatically selects the best available method (scipy for quality, PIL for compatibility) and provides consistent results everywhere.

Cross-platform image blur operations with automatic fallbacks.

Methods

# Platform-optimized blur
blurred_pixmap = GaussianBlurUtils.gaussianBlur(
image, # Path, QPixmap, QImage, or PIL Image
blurRadius=18, # Platform-appropriate blur intensity
brightFactor=1, # Brightness multiplier
blurPicSize=None # Optimization for performance-sensitive platforms
)

# Universal image conversion
pil_image = GaussianBlurUtils.fromQtImage(qt_image) # Works with QImage or QPixmap
qt_pixmap = GaussianBlurUtils.toQPixmap(pil_image) # Convert back to Qt

DominantColor

Smart color extraction that works across all platforms.

# Works on all platforms with local files
dominant_color = DominantColor.getDominantColor(
"image.jpg",
defaultColor=(24, 24, 24)
)

Property Configuration by Platform

PlatformBlur RadiusTint OpacityNotes
Wayland10-15120-180Use fallback-friendly settings
X1120-25100-150Full quality available
Windows20-30100-150Excellent performance
macOS15-20120-180Limited screen access

Color Recommendations

# Platform-adaptive color settings
def get_platform_colors(platform_info):
if platform_info['is_wayland']:
# Wayland: Brighter colors for better fallback visibility
return QColor(255, 255, 255, 180), QColor(255, 255, 255, 20)
elif platform_info['is_x11']:
# X11: Standard acrylic colors
return QColor(242, 242, 242, 150), QColor(255, 255, 255, 10)
elif platform_info['is_windows']:
# Windows: Windows 11 style
return QColor(240, 240, 240, 140), QColor(255, 255, 255, 15)
else:
# macOS/others: Slightly different tint
return QColor(245, 245, 245, 160), QColor(255, 255, 255, 12)

# Usage
platform_info = PlatformDetector.detect_platform()
tint_color, luminosity_color = get_platform_colors(platform_info)

Method Reference

Platform-Aware Methods

success

Smart Methods: These methods automatically adapt to platform capabilities, using native features where available and graceful fallbacks where restricted.

# Apply effect (works everywhere)
acrylic_effect.applyToWidget()

# Grab background with platform intelligence
acrylic_effect.grabFromScreen() # Auto-chooses best method per platform

# Platform-specific configuration
acrylic_effect.setBlurRadius(20) # Adjusted per platform capabilities

# Check current mode
if acrylic_effect.isUsingFallback():
print("Using acrylic fallback mode")
# Adjust UI for fallback appearance

# Get detailed platform info
platform_info = acrylic_effect.getPlatformInfo()
print(f"Running on: {platform_info}")

Advanced Platform Handling

# Force specific behavior (advanced users only)
class CustomAcrylicEffect(AcrylicEffect):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# Override platform detection for testing
if os.environ.get('FORCE_FALLBACK'):
self.acrylicBrush.platform_info['is_wayland'] = True
self.acrylicBrush.using_fallback = True

def grabFromScreen(self, rect=None):
"""Custom screen grab with platform-specific logic"""
if rect is None:
rect = self.widget.rect()

# Custom platform handling
if self.platform_info['is_wayland']:
# Enhanced Wayland handling
self.handle_wayland_specially(rect)
else:
# Use standard method
super().grabFromScreen(rect)

Complete Cross-Platform Examples

Universal Acrylic Sidebar

success

Production-Ready Example: This sidebar implementation works perfectly on all platforms with automatic adaptation to each environment's capabilities.

from Custom_Widgets.AcrylicEffect import AcrylicEffect, PlatformDetector
from qtpy.QtWidgets import *
from qtpy.QtCore import Qt, QTimer
from qtpy.QtGui import QColor, QFont

class UniversalAcrylicSidebar(QWidget):
"""Acrylic sidebar that works on all platforms"""

def __init__(self, parent=None):
super().__init__(parent)
self.setFixedWidth(300)

# Detect platform for adaptive settings
self.platform_info = PlatformDetector.detect_platform()

self.setup_ui()
self.setup_acrylic()

def setup_ui(self):
"""Setup UI with platform-adaptive styling"""
layout = QVBoxLayout(self)
layout.setContentsMargins(20, 50, 20, 20)
layout.setSpacing(10)

# Platform indicator
platform_label = QLabel(
f"{self.platform_info['system'].upper()} - "
f"{self.platform_info['display_server'].upper()}"
)
platform_label.setStyleSheet("""
color: rgba(255, 255, 255, 0.7);
font-size: 10px;
padding: 5px;
background: rgba(0, 0, 0, 0.2);
border-radius: 3px;
""")
platform_label.setAlignment(Qt.AlignCenter)
layout.addWidget(platform_label)

# Title
title = QLabel("Navigation")
title.setFont(QFont("Arial", 18, QFont.Bold))
title.setStyleSheet("color: white;")
title.setAlignment(Qt.AlignCenter)
layout.addWidget(title)

layout.addSpacing(20)

# Navigation buttons
nav_items = [
("🏠 Home", "home"),
("👤 Profile", "profile"),
("⚙️ Settings", "settings"),
("📨 Messages", "messages"),
("🆘 Help", "help")
]

for icon_text, action in nav_items:
btn = QPushButton(icon_text)
btn.setFixedHeight(45)
btn.setObjectName(f"btn_{action}")
btn.setStyleSheet(self.get_button_style())
layout.addWidget(btn)

layout.addStretch()

# Status label
self.status_label = QLabel("Ready")
self.status_label.setStyleSheet("color: rgba(255, 255, 255, 0.6); font-size: 11px;")
self.status_label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.status_label)

def get_button_style(self):
"""Get platform-adaptive button styling"""
if self.platform_info['is_wayland']:
# Brighter for Wayland fallback
return """
QPushButton {
background: rgba(255, 255, 255, 0.25);
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 8px;
color: white;
font-size: 14px;
padding: 10px;
text-align: left;
}
QPushButton:hover {
background: rgba(255, 255, 255, 0.35);
}
QPushButton:pressed {
background: rgba(255, 255, 255, 0.2);
}
"""
else:
# Standard styling for other platforms
return """
QPushButton {
background: rgba(255, 255, 255, 0.15);
border: none;
border-radius: 8px;
color: white;
font-size: 14px;
padding: 10px;
text-align: left;
}
QPushButton:hover {
background: rgba(255, 255, 255, 0.25);
}
QPushButton:pressed {
background: rgba(255, 255, 255, 0.1);
}
"""

def setup_acrylic(self):
"""Setup acrylic effect with platform-adaptive settings"""
# Platform-specific settings
if self.platform_info['is_wayland']:
blur_radius = 12
tint_color = QColor(45, 45, 45, 180) # Darker for better fallback
luminosity_color = QColor(255, 255, 255, 20)
elif self.platform_info['is_x11']:
blur_radius = 22
tint_color = QColor(40, 40, 40, 150)
luminosity_color = QColor(255, 255, 255, 15)
elif self.platform_info['is_windows']:
blur_radius = 25
tint_color = QColor(35, 35, 35, 140)
luminosity_color = QColor(255, 255, 255, 12)
else: # macOS and others
blur_radius = 18
tint_color = QColor(50, 50, 50, 160)
luminosity_color = QColor(255, 255, 255, 18)

# Create acrylic effect
self.acrylic = AcrylicEffect(
widget=self,
blurRadius=blur_radius,
tintColor=tint_color,
luminosityColor=luminosity_color,
noiseOpacity=0.04
)
self.acrylic.applyToWidget()

def showEvent(self, event):
"""Handle show event to setup background"""
super().showEvent(event)

# Delay background grab to ensure widget is visible
QTimer.singleShot(50, self.grab_background)

def grab_background(self):
"""Grab background and update status"""
self.acrylic.grabFromScreen()

# Update status based on acrylic mode
if self.acrylic.isUsingFallback():
mode_text = "Fallback Mode"
color = "#ff9966" # Orange for fallback
else:
mode_text = "Native Mode"
color = "#66ff99" # Green for native

self.status_label.setText(
f"<span style='color: {color}; font-weight: bold;'>{mode_text}</span>"
)
self.status_label.setToolTip(f"Acrylic effect running in {mode_text.lower()}")

class MainWindow(QMainWindow):
"""Main window with platform-adaptive acrylic sidebar"""

def __init__(self):
super().__init__()
self.setWindowTitle("Universal Acrylic Demo")
self.resize(900, 600)

# Set window icon based on platform
self.set_platform_icon()

self.setup_ui()

def set_platform_icon(self):
"""Set platform-appropriate window icon"""
# In real implementation, load appropriate icon files
pass

def setup_ui(self):
"""Setup main UI"""
central = QWidget()

# Platform-adaptive background
if PlatformDetector.detect_platform()['is_wayland']:
# Simpler gradient for Wayland
central.setStyleSheet("""
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #4a6fa5, stop:1 #2e4a76);
""")
else:
# More complex gradient for other platforms
central.setStyleSheet("""
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #667eea, stop:1 #764ba2);
""")

self.setCentralWidget(central)

layout = QHBoxLayout(central)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)

# Add acrylic sidebar
self.sidebar = UniversalAcrylicSidebar()
layout.addWidget(self.sidebar)

# Main content area
content = QWidget()
content_layout = QVBoxLayout(content)
content_layout.setContentsMargins(40, 40, 40, 40)

# Platform info display
platform_info = PlatformDetector.detect_platform()
info_text = f"""
<h2>Cross-Platform Acrylic Demo</h2>
<p><b>Platform:</b> {platform_info['system'].upper()}</p>
<p><b>Display Server:</b> {platform_info['display_server'].upper()}</p>
<p><b>Acrylic Mode:</b> {'Fallback' if self.sidebar.acrylic.isUsingFallback() else 'Native'}</p>
<p><b>Blur Radius:</b> {self.sidebar.acrylic.acrylicBrush.blurRadius}</p>
<hr>
<p style='color: #aaa; font-size: 12px;'>
The acrylic effect automatically adapts to your platform.<br>
On Wayland, it uses fallback methods when screen grabbing is restricted.
</p>
"""

info_label = QLabel(info_text)
info_label.setStyleSheet("""
color: white;
font-size: 14px;
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
padding: 20px;
""")
info_label.setWordWrap(True)
content_layout.addWidget(info_label)

content_layout.addStretch()
layout.addWidget(content)

# Application entry point
if __name__ == "__main__":
app = QApplication([])

# Set application style based on platform
platform = PlatformDetector.detect_platform()
if platform['is_windows']:
app.setStyle("Fusion")
elif platform['is_macos']:
app.setStyle("macos")

window = MainWindow()
window.show()

app.exec_()

Platform-Adaptive Dashboard

tip

Adaptive Design: This dashboard example shows how to create UI components that automatically adjust their appearance and behavior based on the underlying platform.

class AdaptiveAcrylicCard(QWidget):
"""Acrylic card that adapts to platform capabilities"""

def __init__(self, title="Card", content="", parent=None):
super().__init__(parent)
self.title = title
self.content = content
self.platform_info = PlatformDetector.detect_platform()

self.setup_ui()
self.setup_acrylic()

def setup_ui(self):
"""Setup UI with platform-adaptive design"""
self.setMinimumSize(200, 150)
self.setMaximumSize(400, 300)

layout = QVBoxLayout(self)
layout.setContentsMargins(20, 20, 20, 20)

# Title with platform-appropriate styling
title_label = QLabel(self.title)
if self.platform_info['is_wayland']:
title_label.setStyleSheet("""
color: white;
font-size: 18px;
font-weight: bold;
padding-bottom: 5px;
border-bottom: 2px solid rgba(255, 255, 255, 0.3);
""")
else:
title_label.setStyleSheet("""
color: white;
font-size: 18px;
font-weight: bold;
padding-bottom: 10px;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
""")

layout.addWidget(title_label)

# Content
content_label = QLabel(self.content)
content_label.setWordWrap(True)
content_label.setStyleSheet("color: rgba(255, 255, 255, 0.9);")
layout.addWidget(content_label)

layout.addStretch()

# Platform indicator
indicator = QLabel(self.get_platform_indicator())
indicator.setAlignment(Qt.AlignRight)
indicator.setStyleSheet("""
color: rgba(255, 255, 255, 0.5);
font-size: 9px;
font-family: monospace;
""")
layout.addWidget(indicator)

def get_platform_indicator(self):
"""Get platform indicator text"""
platform_map = {
'wayland': 'WL',
'x11': 'X11',
'windows': 'WIN',
'darwin': 'MAC'
}
return platform_map.get(self.platform_info['display_server'],
self.platform_info['system'][:3].upper())

def setup_acrylic(self):
"""Setup acrylic effect with platform-specific settings"""
# Platform-specific colors
colors = {
'wayland': QColor(60, 80, 120, 180),
'x11': QColor(70, 90, 130, 160),
'windows': QColor(80, 100, 140, 150),
'darwin': QColor(90, 110, 150, 170)
}

# Platform-specific blur radius
blur_radius = {
'wayland': 10,
'x11': 22,
'windows': 25,
'darwin': 18
}

# Get settings for current platform
tint_color = colors.get(self.platform_info['display_server'],
QColor(80, 100, 140, 160))
radius = blur_radius.get(self.platform_info['display_server'], 20)

# Create acrylic effect
self.acrylic = AcrylicEffect(
widget=self,
blurRadius=radius,
tintColor=tint_color,
luminosityColor=QColor(255, 255, 255, 15),
noiseOpacity=0.035
)
self.acrylic.applyToWidget()

def showEvent(self, event):
"""Handle show event"""
super().showEvent(event)
QTimer.singleShot(50, self.acrylic.grabFromScreen)

def enterEvent(self, event):
"""Handle mouse enter for interactivity"""
if not self.platform_info['is_wayland']:
# Only animate on platforms with good performance
self.animate_hover(True)
super().enterEvent(event)

def leaveEvent(self, event):
"""Handle mouse leave"""
if not self.platform_info['is_wayland']:
self.animate_hover(False)
super().leaveEvent(event)

def animate_hover(self, hover):
"""Animate card on hover"""
# Implementation depends on animation library
pass

Platform-Specific Troubleshooting

Wayland Issues

danger

Wayland Security: Wayland intentionally restricts screen grabbing for security. This is not a bug but a design decision.

Symptoms:

  • Acrylic effect shows solid color instead of blur
  • Status shows "Fallback Mode"
  • No screen content visible through acrylic

Solutions:

  1. Accept fallback mode - The gradient fallback looks good
  2. Use X11 session - Run with QT_QPA_PLATFORM=xcb
  3. Adjust expectations - Wayland provides security over features
  4. Use alternative effects - Consider CSS backdrop-filter if available
# Check if running on Wayland
if PlatformDetector.detect_platform()['is_wayland']:
print("Wayland detected - using acrylic fallbacks")
# Configure UI for fallback mode
widget.setStyleSheet("""
/* Additional styling for fallback mode */
border: 1px solid rgba(255, 255, 255, 0.1);
""")

X11 Issues

Symptoms:

  • Screen grabbing works but is slow
  • Multi-monitor coordinates incorrect
  • Blur quality poor

Solutions:

  1. Optimize blur radius - Use 20-25 for best performance/quality
  2. Check screen geometry - Verify multi-monitor setup
  3. Update graphics drivers - Ensure proper X11 acceleration

Windows Issues

Symptoms:

  • DWM compatibility problems
  • Performance issues on older hardware
  • Alpha channel problems

Solutions:

  1. Enable DWM composition - Ensure Aero/Desktop composition is enabled
  2. Adjust blur radius - Windows handles blur efficiently at 25-30
  3. Check transparency - Verify window has WA_TranslucentBackground

macOS Issues

Symptoms:

  • Limited screen access
  • Quartz-specific issues
  • Performance on Retina displays

Solutions:

  1. Use appropriate blur radius - 15-20 works best
  2. Check permissions - Ensure screen recording permissions
  3. Retina scaling - Account for device pixel ratio

Debugging and Diagnostics

tip

Comprehensive Debugging: Use this diagnostic function to get complete information about your acrylic setup across all platforms.

def diagnose_acrylic_environment():
"""Print comprehensive diagnostics about acrylic environment"""
from Custom_Widgets.AcrylicEffect import PlatformDetector
import sys

print("=" * 60)
print("ACRYLIC EFFECT DIAGNOSTICS")
print("=" * 60)

# Platform info
platform_info = PlatformDetector.detect_platform()
print(f"\n1. PLATFORM INFORMATION:")
print(f" System: {platform_info['system']}")
print(f" Display Server: {platform_info['display_server']}")
print(f" Is Wayland: {platform_info['is_wayland']}")
print(f" Is X11: {platform_info['is_x11']}")

# Environment variables
print(f"\n2. ENVIRONMENT VARIABLES:")
wayland_vars = ['WAYLAND_DISPLAY', 'XDG_SESSION_TYPE', 'DESKTOP_SESSION']
for var in wayland_vars:
value = os.environ.get(var, 'Not set')
print(f" {var}: {value}")

# Qt information
print(f"\n3. QT INFORMATION:")
print(f" Qt Version: {QtCore.QT_VERSION_STR}")
print(f" PySide/PyQt: {QtCore.__name__}")

# Dependencies
print(f"\n4. DEPENDENCIES:")
try:
import scipy
print(f" scipy: {scipy.__version__} ✓")
except ImportError:
print(f" scipy: Not installed (using PIL fallback)")

try:
import numpy
print(f" numpy: {numpy.__version__} ✓")
except ImportError:
print(f" numpy: Not installed")

try:
from PIL import Image
print(f" PIL: {Image.__version__} ✓")
except ImportError:
print(f" PIL: Not installed")

# Recommendations
print(f"\n5. RECOMMENDATIONS:")
if platform_info['is_wayland']:
print(f" • Use blur radius 10-15")
print(f" • Expect fallback mode")
print(f" • Consider QT_QPA_PLATFORM=xcb for X11 session")
elif platform_info['is_x11']:
print(f" • Use blur radius 20-25")
print(f" • Full screen blur available")
elif platform_info['is_windows']:
print(f" • Use blur radius 25-30")
print(f" • Ensure DWM composition enabled")
elif platform_info['is_macos']:
print(f" • Use blur radius 15-20")
print(f" • Check screen recording permissions")

print("=" * 60)

# Usage
diagnose_acrylic_environment()

Performance Optimization by Platform

Wayland Optimization

# Wayland: Focus on fallback performance
acrylic = AcrylicEffect(
widget=widget,
blurRadius=10, # Lower blur for performance
tintColor=QColor(50, 50, 50, 180), # Stronger tint
luminosityColor=QColor(255, 255, 255, 25) # More luminosity
)

# Use smaller widgets
widget.setFixedSize(300, 200) # Smaller = faster

X11 Optimization

# X11: Full quality available
acrylic = AcrylicEffect(
widget=widget,
blurRadius=25, # Higher quality blur
tintColor=QColor(40, 40, 40, 140), # Standard tint
luminosityColor=QColor(255, 255, 255, 10)
)

# Can use larger widgets
widget.setMinimumSize(400, 300)

Windows Optimization

# Windows: Excellent DWM integration
acrylic = AcrylicEffect(
widget=widget,
blurRadius=30, # Windows handles high blur well
tintColor=QColor(35, 35, 35, 130),
luminosityColor=QColor(255, 255, 255, 8)
)

macOS Optimization

# macOS: Balance quality and compatibility
acrylic = AcrylicEffect(
widget=widget,
blurRadius=18, # Moderate blur
tintColor=QColor(45, 45, 45, 160),
luminosityColor=QColor(255, 255, 255, 15)
)

# Account for Retina displays
if widget.devicePixelRatio() > 1.5:
acrylic.setBlurRadius(14) # Slightly less blur on Retina

Migration Guide

From Older Versions

info

Seamless Migration: The new cross-platform version maintains backward compatibility while adding intelligent platform detection.

# OLD VERSION (platform-specific)
acrylic = AcrylicEffect(widget)
acrylic.grabFromScreen() # Might fail on Wayland

# NEW VERSION (cross-platform)
acrylic = AcrylicEffect(widget)
acrylic.grabFromScreen() # Automatically uses appropriate method

# Check if migration needed
if hasattr(acrylic, 'isUsingFallback'):
print("Using new cross-platform version")
else:
print("Consider updating to cross-platform version")

Platform-Specific Code Migration

# Before: Platform-specific workarounds
if sys.platform == "linux":
if "wayland" in os.environ.get("XDG_SESSION_TYPE", ""):
# Wayland-specific code
use_fallback = True
else:
# X11-specific code
use_fallback = False
elif sys.platform == "win32":
# Windows-specific code
pass
elif sys.platform == "darwin":
# macOS-specific code
pass

# After: Automatic platform detection
acrylic = AcrylicEffect(widget) # Handles everything automatically
if acrylic.isUsingFallback():
print("Using fallback mode on this platform")

Frequently Asked Questions

Q: Why doesn't screen blur work on Wayland?

A: Wayland intentionally restricts screen grabbing for security. This is a feature, not a bug. The acrylic effect automatically uses high-quality fallbacks on Wayland.

Q: How do I force X11 mode on Wayland?

A: Run your application with:

QT_QPA_PLATFORM=xcb python your_app.py

Q: What's the performance impact?

A: Performance varies by platform:

  • Wayland: Excellent (uses optimized fallbacks)
  • X11: Good to excellent (native blurring)
  • Windows: Excellent (DWM optimized)
  • macOS: Good (balanced approach)

Q: Can I customize fallback appearance?

A: Yes, the fallback creates beautiful gradient backgrounds that you can customize via tint and luminosity colors.

Q: How do I know which mode is active?

A: Use acrylic_effect.isUsingFallback() or check the platform info.


Additional Resources

success

Universal Acrylic: The updated AcrylicEffect system provides beautiful, performant frosted glass effects that work consistently across all major platforms, with intelligent adaptation to each environment's capabilities and restrictions.