mirror of
https://github.com/harivansh-afk/deskctl.git
synced 2026-04-18 06:04:06 +00:00
* 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
78 lines
2.2 KiB
Text
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.
|