<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Overview - DWN Documentation</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<button class="mobile-menu-btn">Menu</button>
<div class="layout">
<aside class="sidebar">
<div class="sidebar-header">
<h1>DWN</h1>
<span class="version">v1.0.0</span>
</div>
<div class="search-box">
<input type="text" class="search-input" placeholder="Search docs...">
</div>
<nav class="sidebar-nav">
<div class="nav-section">
<div class="nav-section-title">Getting Started</div>
<a href="index.html" class="nav-link">Introduction</a>
<a href="installation.html" class="nav-link">Installation</a>
<a href="quickstart.html" class="nav-link">Quick Start</a>
</div>
<div class="nav-section">
<div class="nav-section-title">User Guide</div>
<a href="features.html" class="nav-link">Features</a>
<a href="shortcuts.html" class="nav-link">Keyboard Shortcuts</a>
<a href="configuration.html" class="nav-link">Configuration</a>
<a href="layouts.html" class="nav-link">Layouts</a>
<a href="ai-features.html" class="nav-link">AI Integration</a>
</div>
<div class="nav-section">
<div class="nav-section-title">API Reference</div>
<a href="api-overview.html" class="nav-link active">API Overview</a>
<a href="api-reference.html" class="nav-link">API Reference</a>
<a href="api-examples.html" class="nav-link">API Examples</a>
</div>
<div class="nav-section">
<div class="nav-section-title">Advanced</div>
<a href="architecture.html" class="nav-link">Architecture</a>
<a href="building.html" class="nav-link">Building from Source</a>
</div>
</nav>
</aside>
<main class="main-content">
<div class="content">
<div class="page-header">
<h1>API Overview</h1>
<p class="lead">Introduction to DWN's WebSocket API</p>
</div>
<div class="toc">
<div class="toc-title">On this page</div>
<ul class="toc-list">
<li><a href="#introduction">Introduction</a></li>
<li><a href="#enabling">Enabling the API</a></li>
<li><a href="#connecting">Connecting</a></li>
<li><a href="#protocol">Protocol</a></li>
<li><a href="#quick-start">Quick Start</a></li>
<li><a href="#clients">Client Libraries</a></li>
</ul>
</div>
<h2 id="introduction">Introduction</h2>
<p>DWN provides a WebSocket API for full programmatic control of the window manager. This enables:</p>
<ul>
<li><strong>Test Automation</strong> - Automated UI testing and scripting</li>
<li><strong>Custom Hotkeys</strong> - Build custom keyboard shortcuts</li>
<li><strong>Remote Control</strong> - Control DWN from other machines or devices</li>
<li><strong>Integration</strong> - Connect DWN to other applications</li>
<li><strong>Accessibility</strong> - Build alternative input methods</li>
</ul>
<h2 id="enabling">Enabling the API</h2>
<p>The API is disabled by default. Enable it in <code>~/.config/dwn/config</code>:</p>
<div class="code-block">
<pre><code>[api]
enabled = true
port = 8777</code></pre>
</div>
<p>Restart DWN for changes to take effect.</p>
<div class="alert alert-info">
<strong>Security Note:</strong> The API listens on localhost only by default. Be cautious when exposing to network.
</div>
<h2 id="connecting">Connecting</h2>
<p>Connect via WebSocket to <code>ws://localhost:8777</code> (or your configured port).</p>
<h3>Testing with wscat</h3>
<div class="code-block">
<pre><code># Install wscat
npm install -g wscat
# Connect to DWN
wscat -c ws://localhost:8777
# Send a command
> {"command": "list_windows"}
< {"status": "ok", "windows": [...]}</code></pre>
</div>
<h3>Testing with websocat</h3>
<div class="code-block">
<pre><code># Install websocat
cargo install websocat
# Connect and send command
echo '{"command": "list_windows"}' | websocat ws://localhost:8777</code></pre>
</div>
<h2 id="protocol">Protocol</h2>
<h3>Request Format</h3>
<p>All requests are JSON objects with a <code>command</code> field:</p>
<div class="code-block">
<pre><code>{
"command": "command_name",
"param1": "value1",
"param2": "value2"
}</code></pre>
</div>
<h3>Response Format</h3>
<p>Responses include a <code>status</code> field:</p>
<div class="code-block">
<pre><code>// Success
{
"status": "ok",
"data": {...}
}
// Error
{
"status": "error",
"message": "Error description"
}</code></pre>
</div>
<h3>Command Categories</h3>
<div class="table-container">
<table>
<thead>
<tr>
<th>Category</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>Windows</td>
<td>list_windows, focus_window, close_window, move_window, resize_window</td>
</tr>
<tr>
<td>Workspaces</td>
<td>list_workspaces, switch_workspace, move_to_workspace</td>
</tr>
<tr>
<td>Layout</td>
<td>get_layout, set_layout, set_master_ratio</td>
</tr>
<tr>
<td>Keyboard</td>
<td>key_press, key_release, type_text</td>
</tr>
<tr>
<td>Mouse</td>
<td>mouse_move, mouse_click, mouse_drag</td>
</tr>
<tr>
<td>Screenshot</td>
<td>screenshot</td>
</tr>
<tr>
<td>OCR</td>
<td>ocr</td>
</tr>
<tr>
<td>System</td>
<td>get_monitors, spawn, notify</td>
</tr>
</tbody>
</table>
</div>
<h2 id="quick-start">Quick Start</h2>
<h3>List Windows</h3>
<div class="code-block">
<pre><code>// Request
{"command": "list_windows"}
// Response
{
"status": "ok",
"windows": [
{
"id": 12345678,
"title": "Firefox",
"class": "firefox",
"workspace": 0,
"x": 0, "y": 32,
"width": 960, "height": 540,
"focused": true,
"floating": false
}
]
}</code></pre>
</div>
<h3>Focus a Window</h3>
<div class="code-block">
<pre><code>{"command": "focus_window", "window": 12345678}</code></pre>
</div>
<h3>Switch Workspace</h3>
<div class="code-block">
<pre><code>{"command": "switch_workspace", "workspace": 2}</code></pre>
</div>
<h3>Type Text</h3>
<div class="code-block">
<pre><code>{"command": "type_text", "text": "Hello, World!"}</code></pre>
</div>
<h3>Take Screenshot</h3>
<div class="code-block">
<pre><code>// Request
{"command": "screenshot", "mode": "fullscreen"}
// Response
{
"status": "ok",
"format": "png",
"encoding": "base64",
"width": 1920,
"height": 1080,
"data": "iVBORw0KGgo..."
}</code></pre>
</div>
<h2 id="clients">Client Libraries</h2>
<h3>Python Client</h3>
<p>A Python client is included in the <code>examples/</code> directory:</p>
<div class="code-block">
<pre><code>from dwn_api_client import DWNClient
# Connect
client = DWNClient()
client.connect()
# List windows
windows = client.list_windows()
# Focus a window
client.focus_window(windows[0]['id'])
# Take screenshot
result = client.screenshot('fullscreen')
with open('screenshot.png', 'wb') as f:
f.write(base64.b64decode(result['data']))
# Disconnect
client.disconnect()</code></pre>
</div>
<h3>JavaScript (Browser)</h3>
<div class="code-block">
<pre><code>const ws = new WebSocket('ws://localhost:8777');
ws.onopen = () => {
ws.send(JSON.stringify({command: 'list_windows'}));
};
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
console.log(response);
};</code></pre>
</div>
<h3>Web Remote</h3>
<p>A web-based remote control interface is included at <code>examples/web_remote.html</code>. Open it in a browser to control DWN graphically.</p>
<h2>Next Steps</h2>
<ul>
<li><a href="api-reference.html">API Reference</a> - Complete command documentation</li>
<li><a href="api-examples.html">API Examples</a> - Code examples for common tasks</li>
</ul>
<footer>
<p>DWN Window Manager - retoor &lt;retoor@molodetz.nl&gt;</p>
</footer>
</div>
</main>
</div>
<script src="js/main.js"></script>
</body>
</html>