Before every screen share or video call, the first thing everyone sees is my desktop — and it's a mess. I wanted a way to just… cover it. Not hide icons in a dock autohide trick, but literally throw a rug over the clutter. So Desk Rug is a small native macOS app that puts a live, physics-simulated cloth rug on your desktop. One hotkey sweeps the icons underneath it; another brings them back.
The honest part first
I didn't build this from zero. Desk Rug grows out of the MIT-licensed under-the-rug by siliconbag — a wonderful idea that deserved more engineering. My work was taking it apart and rebuilding it where it hurt: solver stability, startup speed, CPU use, and breadth (more rugs, more floors, scheduling, per-Space profiles). Credit where it's due — none of this exists without the original.
How the cloth actually works
The rug is a grid of vertices simulated with XPBD (substepped, in the style of Ten Minute Physics' cloth), not a pre-baked animation:
- A cloth grid of 56 columns at ~19pt spacing — small enough that the piles of icons under the rug deform the fabric into visible bumps and fold ridges.
- The ground is a signed height field with static + kinetic Coulomb friction, so the rug settles, stays put, and slides the way real fabric does.
- Icon piles add bumps to the height field — that's what makes the "hidden icons under the rug" read as a bulge.
- Self-collisions are resolved with a spatial hash, so folds don't clip through each other.
- Coordinates live in screen points — same units as the desktop, which makes dragging, grabbing and releasing predictable.
Rendering
All shaders are MSL compiled at runtime from a source string — no Metal toolchain or precompiled bundle needed, which keeps the app a single thin binary. The rug gets a soft directional light, a 16-tap Poisson soft shadow, and the fleece look comes from a procedural fragment pass on top of the vertex grid.
What I changed vs. the base project
- Solver stability: tighter substep budget, velocity caps and a
maxSpeedguard — no more jitter or "blizzard" wake-up when the rug sits at rest. - Startup & CPU: leaner grid and rendering path; the rug idles nearly at 0% CPU.
- Content: 6 rugs and 6 floors, and you can feed your own images for both (they're treated as UV-mapped fabrics).
- Scheduling: a per-day schedule that sweeps icons under before meetings and restores them after.
- Per-Space profiles: rug, floor and size follow which Space you're on.
- Automation: icons are really moved via Finder (nothing is deleted) and restored to their exact positions around the screen edge. Global hotkey (⌃⌥⌘R) via Carbon.
- 12 rugs→ …and it ships in 13 interface languages.
The fun part of tuning was that cloth parameters are exposed through environment variables (RUG_G, RUG_BEND, RUG_DAMP, RUG_COLS, …) so the demo harness can sweep values without recompiling — very useful when you're chasing "does it settle without a blizzard".
Privacy
No accounts, no analytics, no network calls, no screen-recording permission. The app moves files through Finder on your machine and never sends anything anywhere.
Try it
Free, native Swift, macOS 14+, universal binary. Not notarized yet, so first Open is via right-click → Open.
Download: https://artapps.dev/desk-rug-macos
I'd love to know whether the rebuild lands — especially the feel of dragging the fabric at 60 fps. PRs and issues welcome, respectful on the base project's license.


