Today I want to talk about a collection of small Linux utilities I have been building to support my daily work. Since last year, and through most of this year, Linux has become my primary operating system. Almost all of my AI, C-Kernel-Engine, Antsand, writing, and presentation work now happens there.
I have used Linux for many years, but usually through servers, VirtualBox, or another virtualized environment. Making it the actual host operating system is different. That is where the small UI and hardware details start to matter: Bluetooth headphones, microphones, mouse buttons, displays, screenshots, mounted drives, presentation tools, and software that works cleanly on Windows or macOS but needs a little more help on Linux.
AI changed that trade-off for me. Instead of accepting each annoyance or moving back to another operating system, I can build the narrow utility I need, test it, and keep using it. Most of these tools were developed with substantial help from ChatGPT, and I now use them every day. I thought it would be useful to share what I built, what I learned, and what may help someone who wants to move away from Windows or macOS but was previously hesitant to make Linux the main machine.
A recent failure explains the repository better than a feature list. I mapped the LinuxUtilities control center to a mouse button. It opened correctly when the focused terminal happened to be in the Antsand workspace, but from several other windows it appeared and immediately closed. That is the kind of problem a personal utility is supposed to remove, not create.
The fix was not to pin the application to Antsand. It was to separate two paths that had been treated as one: where the LinuxUtilities program and its assets live, and which working directory the user wants to inspect. That small distinction now shapes the launcher, the GTK application, its logs, and its smoke tests.
The project is available at github.com/antshiv/LinuxUtilities. It is built mostly from C and GTK4, Lua for AwesomeWM, and shell scripts. There is no Electron wrapper or npm application hiding underneath it.
What LinuxUtilities Is
I have used Linux as my primary development environment for more than a decade. My work is spread across terminals, local web servers, C compilers, browser research, screenshots, audio devices, embedded tools, and several machines. The operating system is not merely the place where a text editor runs. It is the control plane through which all of those activities meet.
LinuxUtilities currently has four main layers:
| Layer | Implementation | Responsibility |
|---|---|---|
| Desktop control | AwesomeWM + Lua modules | Bindings, workspaces, widgets, contextual launchers, calendars, audio, network and application actions. |
| Native workbench | C + GTK4 | Screenshot browsing and annotation, utility actions, storage/audio helpers, and a visible control surface. |
| Operational actions | Bash and small Python tools | Capture, mounting, Bluetooth recovery, presentation setup, media cleanup, reminders and build orchestration. |
| Presentation surface | HTML, JavaScript, Gromit and C overlays | Presenter canvas, teleprompter, storyboard playback, cursor spotlight and Wacom-aware launch profiles. |
The Mouse Button Bug Was Really A Path Contract Bug
AwesomeWM binds mouse button 9 to the control center. When there is a focused client, the launcher tries to infer a useful working directory from the window title and then from the process tree under /proc/<pid>/cwd. This is useful: clicking from a terminal in a project should let the screenshot browser inspect that project's Screenshots directory.
But a contextual directory is not necessarily the LinuxUtilities repository. If the application uses that directory to locate its own scripts, icons, and editor assets, a valid context can still be an invalid program root. The resulting GTK process can fail during startup and, because the old launcher discarded its output, the visible symptom is simply a window that flashes and disappears.
The hardened path now has four explicit steps:
- The binding chooses contextual launch when a focused client exists and a stable fallback when it does not.
- The launcher validates the contextual directory before passing it to the application.
LINUXUTILITIES_ROOTidentifies the repository that owns scripts and assets; the positional argument remains the directory being inspected.- Startup is written to
~/.cache/linuxutilities/control-center.log, and the launcher checks that the process survives its first second instead of reporting success merely becausefork()worked.
program_root="$HOME/Workspace/LinuxUtilities"
context_dir="$(resolve_focused_client_directory || printf '%s' "$program_root")"
log_file="$HOME/.cache/linuxutilities/control-center.log"
LINUXUTILITIES_ROOT="$program_root" \
"$program_root/build/bin/linux_control_center" "$context_dir" \
>>"$log_file" 2>&1 &The C application performs its own resolution rather than trusting one caller. It checks the environment root, a requested directory containing the expected editor assets, the current directory, the executable path, and finally the normal home-workspace location. This is not a general plugin system. It is defensive startup logic for a tool that can be invoked from a mouse binding, a desktop entry, a terminal, or a copied binary.
A Screenshot Is Often The Fastest AI Prompt
Much of my work with AI starts with visible state: a broken layout, a profiler report, a shopping cart, an IR graph, a compiler message, or a terminal result. Describing every pixel in prose is slower and less accurate than handing the image to the model with a short question.
The control center therefore treats screenshots as an engineering input surface. It can load a project screenshot directory, select several images, copy their absolute paths, or construct the prompt format I use in terminal AI sessions:
Please analyze these files:
@/home/antshiv/Workspace/project/Screenshots/failure.png
@/home/antshiv/Workspace/project/Screenshots/reference.png GTK owns the clipboard payload directly. The shell import path also supports X11's regular clipboard and primary selection, but first removes stale xclip/xsel owners. This matters because every clipboard owner is an X11 client; leaked helpers eventually produce the confusing Maximum number of clients reached failure. LinuxUtilities now exposes cleanup and recovery commands instead of leaving that failure as terminal folklore.
What The Control Center Actually Controls
The name can sound grander than the program. It is a GTK4 workbench that puts frequently repeated actions in one visible place. The current tabs and launchers cover:
- Screenshots: browse, search, select, annotate, delete, copy paths, and construct AI prompts.
- Audio: inspect routing, switch a Bluetooth headset between microphone and music profiles, and recover a device that remains paired after PipeWire loses its sink.
- Storage: inspect removable drives, mount or eject them, probe Samba shares, and open the setup guide.
- Presentation: start the cursor spotlight, Gromit annotation, presenter canvas, storyboard, teleprompter, Wacom mapping, and Reveal workflow.
- System utilities: open networking, Bluetooth, a terminal, a system monitor, mind maps, Manim tools, and clipboard recovery.
Most buttons do not reimplement the underlying Linux facility. They resolve the intended command, provide a controlled fallback, and report failure in language I can act on. Network access prefers a graphical connection editor but can open nmtui in a terminal. System monitoring prefers btop, then htop, then top. Notes prefer Obsidian, then Joplin, then a terminal editor. The point is not abstraction for its own sake; it is preserving one action when machines have slightly different packages installed.
AwesomeWM Is The Routing Layer
The original rc.lua grew because every useful shortcut landed in one file. It has since been divided into modules for shared helpers, brightness, icons, audio, presenter actions, launchers, calendar behavior, widgets, and bindings. The entry point assembles them; the modules own distinct behavior.
This modularity matters because a desktop configuration can fail before the desktop exists. The repository tests the Lua syntax, stages the complete module tree under a temporary XDG_CONFIG_HOME, checks required bindings and fallback guards, exercises runtime wrappers when a virtual display is available, and dry-runs the installation targets. A new module that works in the repository but is omitted from deployment is a test failure.
Where This Helps C-Kernel-Engine
LinuxUtilities does not make a GEMM faster. It helps preserve the environment in which I can find out why a GEMM is slow or wrong. CKE work routinely involves several terminals, generated C, reference runtimes, profiler output, screenshots, local documentation servers, and experiments on other machines. The utility layer shortens the distance between those surfaces.
For example, I can capture an IR visualizer report, copy the image paths into an AI prompt, keep the relevant project directory attached to the control-center context, and then return to the terminal that owns the benchmark. Presentation tools turn the same evidence into a diagram or video explanation. The CKE nightly report remains the correctness record; LinuxUtilities is the workstation plumbing around investigation and communication.
The Tests Are Small, But They Guard Real Failures
The current local hardening passed two targeted gates on August 3, 2026:
| Gate | What it exercises | Result |
|---|---|---|
tests/awesomewm_config_test.sh | Repository syntax, runtime smoke wrapper, staged XDG tree, module inventory, bindings, launcher fallbacks, and deploy dry-runs. | PASS |
test_linux_control_center_smoke.sh | Builds the GTK4 binary and requires it to stay alive under Xvfb with both a populated repository context and a new empty context. | PASS / PASS |
These are not broad desktop compatibility claims. They encode the failures this repository has actually experienced: missing Lua modules after installation, optional programs launched without a terminal, a GUI that exits during startup, and an empty screenshot directory treated as an exceptional state.
What Remains Personal And Unfinished
LinuxUtilities assumes my Linux habits. AwesomeWM, X11 behavior, Terminator, paths under ~/Workspace, and the applications installed on my machines all influence it. Many actions have fallbacks and host overrides, but this is not a desktop environment intended to hide Linux from its user.
The GTK4 control center is also still being hardened. Some workflows remain scripts, the interface has grown unevenly, Wayland behavior is less exercised than X11, and presentation tooling changes whenever I learn a better way to make technical content. That is acceptable for now. The project earns its keep whenever a failure becomes a reproducible command and then a test.
Source: LinuxUtilities on GitHub. Related reading: What CKE Built In July 2026, CKE Memory Planning, and What Numerical Parity Actually Requires.