Repository navigation
Desktop Widgets
Desktop Widgets turn the wallpaper into an interactive surface. They're not decorations baked into a background image — each one is an independent Quickshell component with persistent positioning, Material You theming, drag-and-drop, grid and snap alignment, monitor awareness, lock-screen behavior and its own configuration.
And the collection isn't closed: a Widget Extension system lets you install third-party widgets straight from GitHub, or develop your own locally with a quick reload loop.
- Open Settings (Super + I) → Desktop Widgets.
- Browse the categories (each card shows a live preview) and click add on something — a clock is a good start.
- It appears on your wallpaper. Drag it wherever you like — a 10 px grid and snap guides appear while dragging, and the position is saved the moment you let go.
- Widgets with extra options have their own configuration page, opened from the same card in Settings.
- When your layout is done, flip Lock widget positions so a stray drag can't move anything.
Two settings worth knowing early: Widget color scheme decides how widgets pick colors from your Material palette, and each widget's lock-screen behavior (hide / keep / center / lock-only) lets you compose a lock screen out of your desktop widgets.
Want more than the built-ins? Jump to Widget Extensions to install community widgets from GitHub.
Everything starts at Settings → Desktop Widgets. Built-in widgets are grouped by category with live previews (loaded progressively, so browsing the catalog doesn't spin up every renderer at once). Add or remove each widget independently; widgets with extra options open their own configuration page from the same card.
Global controls that apply to the whole canvas:
- 10 px alignment grid — appears only while dragging, and quantizes movement to it
- Layout snap alignment — widgets magnetically align to the edges of nearby widgets, with visual guide lines and a bit of hysteresis so they don't jitter in and out of alignment. Grid and snap work independently or together
-
Global widget scale —
0.5×to2.0×, applied by the common widget wrapper (widgets can still have their own size options on top) - Lock widget positions — freeze the layout once you're happy with it
- Single-monitor mode — restrict widgets to one chosen display
- Widget color scheme — see below
Widgets are drawn on their own bottom-layer Wayland window per screen, so they behave like part of the desktop, not like floating app windows. That layer is aware of the rest of the shell:
- Fullscreen apps can hide widgets (following the wallpaper's fullscreen-hiding behavior)
- Wallpaper parallax, workspace movement, Overview transitions and background zoom all carry the widget canvas along — a dedicated widget parallax factor controls how strongly it follows
- Media Mode temporarily replaces the desktop, and the widget window simply stops rendering when it has nothing to show
Drag a widget and its coordinates persist to configuration the moment you let go — the layout survives shell restarts. Each active widget stores an instance ID, widget ID, position, placement strategy and lock-screen behavior. Besides the normal free placement, the architecture also supports wallpaper-aware strategies that analyze the image to find calm (or busy) regions — the same mechanism widgets use to adapt their text color to what's behind them.
Compatible widgets don't hardcode colors; they consume semantic tokens (card background, text, subtext, accent, on-accent, pill background, success, warning, outline…) from a shared Widget Color Scheme. You pick the scheme for the whole desktop: Default Surface, Expressive Primary / Secondary / Tertiary, Hero Primary, Vibrant Mix, Muted Low Surface, Secondary Fixed, Tertiary Showcase, Error Alert, Inverse Surface or Tri-Color Blend. All of them reference Material palette roles, so a wallpaper change recolors every compatible widget automatically. Shared outer/inner shadow settings add consistent depth when you want it.
Every active widget chooses what happens when the screen locks:
| Behavior | Effect |
|---|---|
| Hide | Disappears while locked (the default) |
| Keep | Stays exactly where it is |
| Center | Moves into the lock screen's centered layout |
| Lock only | Hidden on the desktop, appears only while locked |
Several widgets can use Center at once — the lock screen arranges them as a group using each widget's real size and configured spacing, so you can compose a custom lock screen out of ordinary desktop widgets.
A quick tour of the categories. (The set keeps growing — the Widget Manager is always the authoritative catalog.)
From classic to frankly experimental: Cookie, Digital, Nagasaki (+ text variant), Flex, Hori, Nothing Digital, Nothing Wheel, Word, Dial, WearOS, WearOS Arc, Concentric, Month, Scallop Dot, Scallop Number, Circle Pointer, Triple Ring, Grid Card and Expressive Card clocks. Many have their own configuration pages for typography, shapes, indicators and colors.
Connected to the active MPRIS player: Circular Media (and the Watch variant), Expressive, Android-style, CD, Nothing Ring and Compact Media — showing artwork, track info, progress, lyrics, visualizers and playback controls depending on the design. The Circular Media Watch adds a 3D glass dome reflection — vector crescents, blur and masking simulating light on a smartwatch lens. Purely visual, and transparent to clicks, so the controls underneath stay usable.
Default and Expressive layouts, a 2×1 forecast, Weather Card, Icon Shape, Pill, Circle Cookie, Nothing Circle, Typography and Hourly variants — compact temperature chips up to full forecast cards.
Date Card, Calendar Minimal, Month Grid, Agenda, Next Event, Pill and Upcoming-3-Days. Calendar widgets read the shell's calendar stack (including the khal-based service when configured), so they can show real upcoming events, not just today's date.
Photo, Photo 1×1, Photo Weather, Photo Pill Badge and Photo Minimal Temperature — personal images in Material framing, some blended with live weather.
Battery state for everything around you: Bluetooth Device Battery, Bluetooth Headphone (+ Cookie variant), Bluetooth Fill Cards, Earbuds Stem, Mobile Phone Battery (via KDE Connect), PC Battery Bars, PC Battery Cable, and a Connected Devices Battery List.
Interactive quick-toggle pills right on the wallpaper: Volume Mute, Wi-Fi, Bluetooth, Microphone, Dark Mode, Screen Recording and EasyEffects — flip them without opening the Dashboard.
CPU, RAM and disk monitoring as pills, fill cards and Nothing-inspired variants, showing usage, temperature and progress fills.
Where the fun stuff lives: Email Inbox (1×1 and 2×1), AI Chat, Notes (1×1 / 2×1), Quick Actions, Android Search Bar, Search Pill, Quote, Water Reminder and At a Glance.
A context-sensitive status surface inspired by the Pixel launcher. It watches several sources — media, calendar, sports scores, to-do (with the Dashboard's optional TickTick sync), unread email, LocalSend transfers, KDE Connect (including low phone battery), weather — keeps a list of currently relevant contexts, and shows the most interesting one. Date + weather is the calm fallback.
When several contexts are active you can flip between them manually, or use the dual-column layout to show two at once. Clicking acts on the context: toggle playback, open the to-do list, jump to the calendar, refresh weather. And it's a file-drop target: drag files onto it and they're shared via LocalSend, falling back to KDE Connect when a device is available.
A hydration tracker with a daily goal, glass counter and progress display — plus a background service that keeps working even when the widget isn't on screen: at your configured interval it checks the goal and sends a reminder notification, congratulates you on the last glass, and resets automatically at midnight. State persists across restarts.
A compact launcher pill with three configurable action buttons plus a main action, choosing from: Search, AI Chat, Music Recognition, Translator, Wallpapers, Phone/KDE Connect, Cheat Sheet, Clipboard, Color Picker and Screenshot. The AI icon can adopt a provider identity (Gemini, OpenAI, Claude, DeepSeek, OpenCode, Ollama, Mistral, OpenRouter, several distro logos) — or Auto, following the active AI provider.
Third-party widgets install from a GitHub URL, a user/repo shorthand, or a local absolute path. A valid extension ships a widget.json manifest describing name, description, version, author, category, icon, the QML component, configuration defaults and an optional configuration schema.
-
Git installs are cloned into
~/.config/quickshell/ii/user_widgets/, validated, and registered into the widget registry under theext:<id>namespace (no collisions with built-ins). Updating from Settings makes a timestamped backup (user_widgets/.backups/) before a fast-forward pull and manifest reload. - Local installs use your directory in place — no copying. That gives you a tight dev loop: edit the QML, hit Reload Widget, look at the desktop. Repeat.
-
Configuration for extensions lives in its own file,
~/.config/illogical-impulse/widget_extensions.json, keeping dynamically-shaped third-party config out of the typed main config tree. If an extension provides aconfigSchema, Settings generates its configuration UI — no need for extensions to ship their own settings pages. - Management — enable/disable, add to or remove from the desktop, configure, update, reload, uninstall — all from Settings.
The Browse Community Widgets section discovers repositories on GitHub tagged with the topic ii-desktop-widget (up to 30 per query, sorted by stars) and shows name, author, description, stars and install state — one-click install for compatible ones.
⚠️ A widget is code. Extensions are executable QML loaded into your shell session — treat them like any software you install, not like passive theme data. A malicious widget can run processes and access anything your Quickshell session can. Only install from sources you trust.
If your configuration references a widget that no longer resolves (an uninstalled extension, say), a Missing Widget Placeholder takes its spot instead of breaking the whole canvas.
The core lives in modules/ii/background/:
| File | Role |
|---|---|
BackgroundWidgetsWindow.qml |
The per-screen Wayland background window: monitor + fullscreen handling, wallpaper/parallax/Overview/lock transformations, canvas hosting |
widgets/WidgetsRegistry.qml |
Central registry: built-in widget metadata merged with enabled extensions |
widgets/WidgetStateManager.qml |
Syncs persistent activeWidgets config with the runtime model: add/remove, coordinates, placement, lock behavior, staggered layout changes, config migration |
widgets/WidgetDelegate.qml |
Instantiates the right component per active widget (built-ins by ID, extensions from their installed paths) and passes shared runtime info |
widgets/AbstractBackgroundWidget.qml |
The common wrapper every widget inherits: dragging, bounds, grid & snap (with WidgetDragMath.js), persistence, global scale, lock behavior, wallpaper-aware placement and text-color helpers |
services/WidgetColorScheme.qml |
The semantic color roles behind the widget palette system |
services/WidgetExtensionManager.qml + scripts/widget_extensions.py
|
Extension lifecycle: git/local install, manifests, config, backups, updates, community discovery |
Layout is stored in Config.options.background.activeWidgets (one entry per instance: id, widgetId, x, y, placementStrategy, lockBehavior), global preferences under Config.options.background.widgets, and per-widget option blocks alongside them.
Built-in widgets inherit AbstractBackgroundWidget and get coordinates, dragging, scaling, lock behavior, grid/snap and persistence for free — visual design should lean on the shared Material tokens and WidgetColorScheme rather than fixed colors. For anything not destined for the main repository, use the Widget Extension format instead of editing WidgetsRegistry.qml; the dev loop with a local install and Reload is genuinely pleasant.