Skip to content

Shadows, Blur, Rounded Corners ​

📖

Problem ​

Modern shells use depth: shadows separate popups from backgrounds, blur creates frosted-glass effects, rounded corners soften edges. QML provides these effects, but applying them without performance impact requires care.

Naive Approach ​

Wrap everything in DropShadow, GaussianBlur, and set radius everywhere. Your shell drops to 15 FPS because every pixel is being blurred in software.

MentalModel ​

💡Mental Model

Every visual effect adds a render pass. Qt's scene graph draws items from back to front. Shadows and blur require off-screen rendering, reading pixels back, and re-compositing. The cost is proportional to the pixel area covered. Small, sparse effects are cheap; full-screen blur is expensive.

Idea ​

Use Qt's DropShadow for shadows, GaussianBlur (from Qt5Compat.GraphicalEffects or Quickshell's built-in) for blur, and radius on Rectangle for corners. Limit blur to small areas like popup backgrounds. Use ShaderEffect for efficient blur if Quickshell provides it.

Build It ​

qml
import QtQuick
import Qt5Compat.GraphicalEffects

PopupWindow {
  width: 300
  height: 400

  Rectangle {
    anchors.fill: parent
    radius: 12
    color: "#ee1e1e2e"

    layer.enabled: true
    layer.effect: GaussianBlur {
      radius: 8
      samples: 16
    }
  }

  Text {
    text: "Frosted content"
    anchors.centerIn: parent
    color: "#ffffff"
  }

  layer.enabled: true
  layer.effect: DropShadow {
    transparentBorder: true
    radius: 16
    samples: 24
    color: "#80000000"
    horizontalOffset: 0
    verticalOffset: 4
  }
}

BuildIt Breakdown ​

The outer layer.effect applies a DropShadow to the entire popup. The inner Rectangle uses layer.enabled: true with a GaussianBlur effect for the frosted-glass background. samples controls quality — higher values look smoother but are slower. The background color includes alpha (#ee...) so the blur shows through.

Improve It ​

Cache blurred layers by rendering once and reusing. Use Quickshell's BlurBehind property on windows when available (Wayland compositor-side blur). Reduce blur radius on low-end GPUs. Add a shadowSpread property to control shadow softness.

CommonMistake ​

⚠️Common Mistake

Applying blur to the root item of every window. Full-window blur forces a full-screen render-to-texture pass on every frame. Keep blur confined to small overlay panels.

Under the Hood ​

🔧Under the Hood

Qt's DropShadow and GaussianBlur use GLSL shaders via the Qt Quick scene graph. layer.enabled: true redirects the item subtree to an off-screen FBO (framebuffer object). The effect shader samples this FBO as a texture. On Wayland, Quickshell's PanelWindow can request kde-blur or background-blur protocols — these are compositor-side effects that bypass Qt's rendering pipeline entirely and are essentially free.

Exercises ​

⭐Exercise

Add a drop shadow to a panel window.

⭐Exercise

Create a popup menu with frosted-glass background using GaussianBlur on only the background rectangle.

⭐Exercise

Build a GlassPanel component that combines blur, shadow, and a subtle border glow with configurable tint and opacity.

Recap ​

✅What You've Learned

Built with VitePress. Licensed under MIT.