deskctl/site/src/pages/architecture.mdx
Hari 3819a85c47
tests and tooling (#4)
* init openspec

* clean out src, move mod into lib, remove trash

* create tests

* pre-commit hook

* add tests to CI

* update website

* README, CONTRIBUTING and Makefile

* openspec

* archive task

* fix ci order

* fix integration test

* fix validation tests
2026-03-25 19:29:59 -04:00

78 lines
2.2 KiB
Text

---
layout: ../layouts/DocLayout.astro
title: Architecture
toc: true
---
# Architecture
## Client-daemon model
deskctl uses a client-daemon architecture over Unix sockets. The daemon starts automatically on the first command and keeps the X11 connection alive so repeated calls skip the connection setup overhead.
Each command opens a new connection to the daemon, sends a single NDJSON request, reads one NDJSON response, and exits.
## Wire protocol
Requests and responses are newline-delimited JSON (NDJSON) over a Unix socket.
**Request:**
```json
{ "id": "r123456", "action": "snapshot", "annotate": true }
```
**Response:**
```json
{"success": true, "data": {"screenshot": "/tmp/deskctl-1234567890.png", "windows": [...]}}
```
Error responses include an `error` field:
```json
{ "success": false, "error": "window not found: @w99" }
```
## Socket location
The daemon socket is resolved in this order:
1. `--socket` flag (highest priority)
2. `$DESKCTL_SOCKET_DIR/{session}.sock`
3. `$XDG_RUNTIME_DIR/deskctl/{session}.sock`
4. `~/.deskctl/{session}.sock`
PID files are stored alongside the socket.
## Sessions
Multiple isolated daemon instances can run simultaneously using the `--session` flag:
```sh
deskctl --session workspace1 snapshot
deskctl --session workspace2 snapshot
```
Each session has its own socket, PID file, and window ref map.
## Backend design
The core is built around a `DesktopBackend` trait. The current implementation uses `x11rb` for X11 protocol operations and `enigo` for input simulation.
The trait-based design means adding Wayland support is a single trait implementation with no changes to the core, CLI, or daemon code.
## X11 integration
Window detection uses EWMH properties:
| Property | Purpose |
| --------------------------- | ------------------------ |
| `_NET_CLIENT_LIST_STACKING` | Window stacking order |
| `_NET_ACTIVE_WINDOW` | Currently focused window |
| `_NET_WM_NAME` | Window title (UTF-8) |
| `_NET_WM_STATE_HIDDEN` | Minimized state |
| `_NET_CLOSE_WINDOW` | Graceful close |
| `WM_CLASS` | Application class/name |
Falls back to `XQueryTree` if `_NET_CLIENT_LIST_STACKING` is unavailable.