Taskbar Buddy

A crayon-drawn desktop buddy for Windows that lives on the taskbar. After an hour of screen time it climbs out through a chalk portal and tells you to stand up, stretch, or get off screen for a few minutes.

Solo — design, drawing and code
2026
  • Electron
  • JavaScript
  • SVG
  • Web Animations API
Taskbar Buddy, a blue crayon-drawn character with a wide toothy grin, standing on a hand-drawn green hill that stretches along the Windows taskbar.

A break reminder that arrives as a notification in the corner is easy to dismiss without reading. So I made one that is harder to wave away: a small blue crayon buddy that lives on my Windows taskbar and, after an hour of screen time, climbs out to tell me to get up.

A Windows desktop. A small blue crayon-drawn buddy sitting on the taskbar climbs up onto it, draws two chalk portals, and rises out of one in the middle of the screen with a speech bubble: “You've been sitting for an hour straight. Time to stand up, stretch, or get off screen for 5–10 minutes.” The “Alright, thanks bud!” button is clicked, and the buddy goes back through the portals and climbs down behind the taskbar.

The whole reminder, from the taskbar to the middle of the screen and back.

What it does

After an hour of screen time the buddy wakes up: it blinks twice, its colour comes in, and it pulls itself up onto the taskbar. It chalks two portals — one on the taskbar, one in the middle of the screen — hops into the first, and rises half-way out of the second to wave and ask me to stand up, stretch, or get off screen for five to ten minutes.

Clicking “Alright, thanks bud!” sends it back the way it came. It walks home, climbs down behind the taskbar and goes back to being a drawing. Everything else lives in the tray menu: remind me now, pause the timer, start with Windows, quit.

Counting only the time I am actually there

An hour on the clock is not an hour at the screen. Every second the app asks Electron how long the system has been idle, and five minutes without mouse or keyboard input counts as a real break and resets the count. Locking the screen or putting the machine to sleep resets it too.

The counting is one pure function, kept free of Electron so it can be tested with plain Node:

timer.js
const LIMIT = Number(process.env.BUDDY_LIMIT) || 3600; // seconds of screen time before a reminder
const BREAK = 300; // this much idle time counts as a real break and resets the counter

const tick = (activeSec, idleSec) => (idleSec >= BREAK ? 0 : activeSec + 1);

BUDDY_LIMIT is there for testing. Nobody wants to wait an hour to find out whether an animation works.

A window you cannot see

There is no visible window at all. The buddy is drawn inside one transparent, frameless window that covers the whole primary display, sits above everything else, and ignores the mouse — clicks fall straight through to whatever is underneath. The only part that ever becomes clickable is the speech bubble, and only while the pointer is over it:

main.js
win.setIgnoreMouseEvents(true, { forward: true });
ipcMain.on('clickable', (_, on) => win.setIgnoreMouseEvents(!on, { forward: true }));

forward: true is what makes that possible. The window keeps receiving mouse-move events while it ignores clicks, so the bubble can notice the pointer arriving and ask for clicks to be switched on.

Crayon, not vectors

Everything on screen is SVG — the taskbar scene, the portals, the buddy — but none of it is allowed to look like SVG. A single filter does the work: turbulence noise displaces every line so it wobbles, and a second, finer noise eats into the fill like wax grain. Swapping the noise seed every 160 ms makes the lines boil, the way hand-drawn animation shimmers between frames.

The buddy is rigged rather than drawn frame by frame. Each part — both arms, both legs, the eyelids, the whole body for its idle bob — is its own named SVG group with its own pivot, animated with the Web Animations API. Going through a portal is a clipping trick: the buddy lives inside a box with overflow: hidden, and moving that box's bottom edge to the portal's line makes everything below it disappear.

With prefers-reduced-motion set, every step of the sequence is shortened to almost nothing, so the reminder still appears without the performance.

What it does not do yet

Clicking the real taskbar lifts it above other always-on-top windows, buddy included. For now the fix is blunt — the window re-asserts its place once a second — so after a click the buddy can vanish for up to a second. A native SetWinEventHook module would fix it properly.

It also only knows about the primary monitor with the taskbar at the bottom, and there is no installer: it runs with npm start.

Something to say?

Thoughts, corrections, or just hello. It goes straight to Farish and is not published anywhere — no other visitor can see it.

Up to 2000 characters. No email address needed.