FakeRing: How I Turned My Monitor Into a $10 Ring Light

FakeRing: How I Turned My Monitor Into a $10 Ring Light

My webcam's brightness failed me during a crucial meeting. Instead of buying a ring light, I built one using Go, Wails v3, and some Win32 magic.

โ€ข By Ehsan Pourhadi โ€ข
Go Wails Open Source Desktop Apps

I have a problem: My room is dark, and my webcam isโ€ฆ well, temperamental. ๐Ÿ’ก

A few days ago, I was hopping into a meeting and my webcam decided it didnโ€™t want to adjust its brightness. I looked like a silhouette in a witness protection program. I didnโ€™t have any lamps nearby, so in a moment of desperation, I opened a blank Chrome tab with about:blank.

Suddenly, my face was illuminated. It worked. Wait, I thought, why donโ€™t I just make this a real thing?

And thatโ€™s how FakeRing was born.

demo


๐Ÿ—๏ธ The Tech Stack: Go meets the Desktop

Iโ€™ve been playing around with Go and Wails v3 recently. If you havenโ€™t tried Wails, itโ€™s like Electron but with a Go backendโ€”way lighter and surprisingly powerful.

I used my own create-wails-app to get started, and then I went to battle with the Windows API.

1. Monitor Detection (The โ€œWhere am I?โ€ problem)

To make a ring light for every monitor, I first had to find out how many monitors the user actually has.

Wails handles the UI beautifully, but for the deep OS-level stuff, I had to talk directly to user32.dll using Goโ€™s syscall package. We use EnumDisplayMonitors to catch every screen and GetMonitorInfoW to get the exact coordinates of the โ€œWork Areaโ€ (so we donโ€™t cover the taskbar).


๐ŸŽจ โ€œThe Magic Ringโ€: How it works

demo

The goal was to draw a ring on top of everything else, but it shouldnโ€™t block your clicks. Imagine having a ring light that prevents you from clicking the โ€œMuteโ€ button. Pure chaos. ๐Ÿคก

The Secret Recipe:

  1. WS_EX_LAYERED: This lets us use transparency and alpha blending.
  2. WS_EX_TRANSPARENT: This is the magic flag. It makes the window โ€œclick-through.โ€ The mouse events just pass right through to the apps behind it.
  3. Colorkeying: I fill the window background with Magenta (0xFF00FF) and then tell Windows: โ€œHey, make this specific color 100% invisible.โ€

๐Ÿงฉ Interactive: Visualize the Ring Geometry

The ring isnโ€™t just a border; itโ€™s a subtraction. We take a โ€œLarge Rectโ€ (the screen) and subtract a โ€œSmaller Rectโ€ ( the inside) to create a perfect โ€œDonutโ€ or โ€œFrame.โ€

Try adjusting the slider below to see how the subtraction creates the ring.

Monitor Preview

๐Ÿง  Brain-Breakers and Lessons Learned

Building desktop apps isnโ€™t all sunshine and rainbows. Here are three things that almost made me throw my keyboard:

1. BGR vs RGB ๐ŸŒˆ

Windows GDI (the drawing engine) is old school. It doesnโ€™t use the standard RGB format we use in CSS. It uses BGR (Blue-Green-Red). My first attempt at a yellow ring came outโ€ฆ blue. I had to do some bit-shifting in Go to swap the channels.

2. The Thread Lock ๐Ÿ”’

Win32 windows are โ€œneedy.โ€ They are tied to the specific thread that created them. If you create a window in a goroutine and that goroutine finishes, your window disappears. I had to use runtime.LockOSThread() to keep the window message loop alive and stable.

3. Debouncing is Life โฑ๏ธ

When you move the color slider in the UI, it sends events fast. If I saved the settings to config.json every time the mouse moved a pixel, the app would lag like crazy. Pro Move: I implemented a 500ms debounce. Visual updates happen instantly (GDI is fast!), but the disk save only happens when you stop fidgeting.


๐ŸŽ“ The โ€œPro Moveโ€ for Debugging

If youโ€™re ever building something like this and want to see whatโ€™s happening without the UI, check your home folder for the hidden config files. In FakeRing, itโ€™s ~/.fakeRing/config.json. Seeing the raw data change while you poke at the app is the best way to understand the bridge between React and Go.

Wrap Up

FakeRing started as a โ€œdesperation toolโ€ for a dark meeting, but it turned into a fun deep dive into the guts of Windows. Itโ€™s open source, itโ€™s light, and it saves me from buying a $10 lamp.

What weird problem are you going to solve today with code? Let me know! ๐Ÿš€

Tags: #Windows API #React #GDI #Productivity
Ehsan Pourhadi
Software Developer

Experienced software developer passionate about creating impactful digital experiences with modern web technologies and thoughtful design.

70+
Projects Completed
50+
Happy Clients
12+
Years Experience
100%
Client Satisfaction
ยฉ 2025 Ehsan Pourhadi. All rights reserved.
Made with
and
using
TreeStone
Running cat