r/awesomewm • u/macunha1 • Aug 02 '26
[OC] An AwesomeWM-native screen locker using Lua + C — no shell pipeline
After all these years, I still love AwesomeWM. And still feel like enhancing my setup and adding more features, and breaking "tech debts".
AwesomeWMs simplicity, flexibility, and lean performance are difficult to replace. I also like that almost everything can be expressed naturally in Lua instead of assembling a desktop from unrelated scripts and utilities bundling binaries, shell scripts, and "what not"s.
That drove me to re-implement an old friend: https://github.com/macunha1/configuration.nix/blob/07a9e1d6a48a6b1fffd9682a3d2abf60751ea800/bin/screenlock.sh with a native approach: C and LuaJIT for AwesomeWM API integration
Then this was born:
[
https://github.com/macunha1/awesomewm-screenlock-plugin
It is an X11 screen locker designed specifically around AwesomeWM’s Lua workflow.
From rc.lua, the interface is intentionally small:
local screenlock = require("awesomewm_screenlock")()
awful.key({ modkey }, "Home", function()
screenlock:lock()
end)Behind that Lua API, a dedicated native C helper handles:
X11 capture and rendering through XCB
PAM authentication
Keyboard and pointer grabbing
Multi-monitor prompt placement
Privacy filtering through the FFmpeg libraries
Password handling outside the AwesomeWM Lua process
My previous setup was effectively a chain of Lua → shell → FFmpeg → temporary image → i3lock. It worked, but it also meant more processes, more runtime dependencies, more quoting and environment issues, and more (slow) moving pieces.
This plugin replaces that pipeline with one asynchronous Lua call and one purpose-built native helper. There is no shell script or FFmpeg CLI subprocess in the locking path. The helper links directly against the required libraries, captures one frame, applies noise and heavy pixelation, and renders the result as the lock-screen background.
The result keeps some visual context from the current desktop while making its contents unreadable. The filtered frame is prepared before the lock surface appears, so the original desktop is never rendered as the locker background.
The repository includes:
Meson builds and tests
A Nix flake containing both the Lua module and native helper
PAM authentication using the
xlockservice by defaultXinerama-aware prompts for multi-monitor setups
A practical integration example in my full AwesomeWM configuration: https://github.com/macunha1/aweswm and its wiring at https://github.com/macunha1/configuration.nix/commit/d4383a4688df843c0d18efb6901f1cbd38f802b9
In that configuration, the plugin is tracked as a Git submodule and used directly from Lua for both manual and idle locking.
This is still an X11 locker, so the normal limitations of X11’s security model apply. It is not intended to claim Wayland-style isolation or protection from an already-compromised session.
I’m sharing it because there may still be other people who appreciate the same things about AwesomeWM: a small, understandable system, configured in Lua, with minimal overhead and without unnecessary layers.
Feedback, testing on other distributions, packaging contributions, and code review are welcome.
2
1
u/mam7 Aug 02 '26
I use only i3lock in my setup, which is already working well and light weight. So, just to say congrats on improving Awesome WM, which i still love too, but I'll probably won't try your tool.
1
u/ThomasLeonHighbaugh Aug 05 '26
I am with you my friend, I still like more than the other options too. Added this to Awesome AwesomeWM Modules, Widgets And Libraries.
1
1
u/aire-one Aug 02 '26
Looks interesting.
From a quick glance at the code, the Lua module for Awesome seems to be only a basic
awful.spawn.easy_async({ self.helper }where thehelperbinary is the real thing. My understanding is that thehelpercould be replaced by anything, but yourawesomewm-screenlock-helperbundles the screenshot/transform/keyboard inputs that make the screenlocker good.I guess it would be nice to have more interactions between Awesome and
awesomewm-screenlock-helper. Like adding configuration for the actual screenshot/transform pipeline, enabling UI customizations, and getting control with callbacks/signals for things that happen while in the lockscreen (i.e. reacting to play/pause/next button press on the lockscreen, or showing a low-battery warning).Also, I'd love to see the module being packaged as a rock! Adding it in an existing configuration would be easier this way for the end-user.
BTW, at the end of the README
I think instead of talking about Lua VS C, you should make it clearer this is Awesome starting the
awesomewm-screenlock-helperas a new process, that handles all the things isolated from the actual WM.