xcreen

A tray application to adjust external monitor brightness using DDC/CI.

Rust

How it Started

During a five-month break from university, I spent hours at my desk every day. A few months in, I started getting serious eye strain from my bright monitor. Unlike my laptop, which has accessible brightness controls and automatic brightness features, the monitor relied on manual controls through an OSD. Having to reach around the back to fiddle with a menu every time I wanted to change the brightness felt cumbersome, and I was worried about the button’s longevity. I wondered whether I could control the monitor over HDMI when it was connected to my laptop, and I found a couple of solutions.

I tried one and immediately ran into multiple problems. For a tool that only did one thing, it was a full Electron bundle that used over 200 MB of memory on average; it felt sluggish and heavy.

At that point I decided to tackle the problem myself. I felt I could build something much simpler and more efficient, something I could run on my laptop 24/7.

A New Challenge

I discovered the DDC/CI protocol, which allows data transmission between computers and monitors over HDMI. It seemed straightforward enough to start coding, but I didn’t want to rely on a library that added multiple layers of abstraction. I wanted to try something new. Besides, what’s the fun in doing it the easy way? So I took the opportunity to explore Rust.

I first started with Rust when I tried out Tauri a couple of years ago. With some rough knowledge of C++ and the Windows API, I quickly scaled up once I got comfortable with the new syntax. As I dug in, I enjoyed the process immensely. Integrating with the Windows went smoothly and was straightforward, with less boilerplate.

Rust’s ownership model and borrow checker forced me to think differently about memory management. Besides, I didn’t felt like Rust was dragging me down, contrary to some critism Rust keeps getting.

I used Tauri to bootstrap the project, building a frontend while Rust handled Windows integrations. Once everything worked, I stripped out Tauri and went fully native, producing a single xcreen.exe file just under 1 MB. That mattered to me a lot, as I felt the need to keep things as minimal as possible.

Overall, I learned more in a few weeks working on xcreen than in months of tinkering with higher-level languages. Rust’s steep learning curve paid off with a deeper understanding of systems programming, and it has encouraged me to use Rust for more ambitious projects I plan to work on.

It Felt Personal

I use xcreen every single day, and I can’t overstate how much I love it. The feeling of “I built this thing!” hasn’t faded. It saves me time, preserves the simplicity I wanted, and lets me focus on what matters; to write code, not fiddle with settings. If you work on multiple screens in varying conditions, xcreen might be the missing piece in your setup.

I’ll continue improving it and may add a few more features. You can check out the project on GitHub; I’ve included installation steps and usage details. It’s open source under the MIT license, so feel free to contribute or adapt it for your needs.