Client Commands

get_clients

Get list of all managed clients (windows).

// Request
{"command": "get_clients"}

// Response
{
    "status": "ok",
    "clients": [
        {
            "window": 12345678,
            "title": "Window Title",
            "class": "window-class",
            "workspace": 0,
            "x": 0,
            "y": 32,
            "width": 960,
            "height": 540,
            "focused": true,
            "floating": false,
            "fullscreen": false,
            "maximized": false,
            "minimized": false
        }
    ]
}

find_clients

Search for clients by title, class, or workspace.

// Request - find by title (substring match)
{"command": "find_clients", "title": "Firefox"}

// Request - find by class
{"command": "find_clients", "class": "terminal"}

// Request - find by workspace
{"command": "find_clients", "workspace": 2}

// Request - combine filters
{"command": "find_clients", "class": "code", "workspace": 0}

// Response
{
    "status": "ok",
    "clients": [...]
}

get_focused_client

Get the currently focused client.

// Request
{"command": "get_focused_client"}

// Response
{
    "status": "ok",
    "client": {
        "window": 12345678,
        "title": "...",
        "class": "...",
        ...
    }
}

focus_client

Focus a client by window ID. Switches workspace if needed.

// Request
{"command": "focus_client", "window": 12345678}

// Response (returns current status)
{
    "status": "ok",
    "version": "2.0.0",
    "current_workspace": 0,
    "client_count": 5
}

close_client

Close a client gracefully (sends WM_DELETE_WINDOW).

// Request
{"command": "close_client", "window": 12345678}

// Response
{"status": "ok"}

kill_client

Force kill a client (XKillClient). Use when close_client fails.

// Request
{"command": "kill_client", "window": 12345678}

// Response
{"status": "ok"}

move_client

Move a client to specified position.

// Request
{
    "command": "move_client",
    "window": 12345678,
    "x": 100,
    "y": 100
}

// Response
{"status": "ok"}

resize_client

Resize a client to specified dimensions.

// Request
{
    "command": "resize_client",
    "window": 12345678,
    "width": 800,
    "height": 600
}

// Response
{"status": "ok"}

minimize_client

Minimize a client.

{"command": "minimize_client", "window": 12345678}

restore_client

Restore a minimized client.

{"command": "restore_client", "window": 12345678}

maximize_client

Maximize or unmaximize a client. Toggles if state not specified.

// Toggle maximize
{"command": "maximize_client", "window": 12345678}

// Set explicit state
{"command": "maximize_client", "window": 12345678, "state": true}

fullscreen_client

Set client fullscreen state. Toggles if state not specified.

// Toggle fullscreen
{"command": "fullscreen_client", "window": 12345678}

// Set explicit state
{"command": "fullscreen_client", "window": 12345678, "state": true}

float_client

Set client floating state. Toggles if state not specified.

// Toggle floating
{"command": "float_client", "window": 12345678}

// Set explicit state
{"command": "float_client", "window": 12345678, "state": true}

raise_client

Raise client to top of stack.

{"command": "raise_client", "window": 12345678}

lower_client

Lower client to bottom of stack.

{"command": "lower_client", "window": 12345678}

Workspace Commands

get_workspaces

Get list of all workspaces.

// Request
{"command": "get_workspaces"}

// Response
{
    "status": "ok",
    "workspaces": [
        {
            "id": 0,
            "name": "1",
            "layout": 0,
            "client_count": 3
        },
        {
            "id": 1,
            "name": "2",
            "layout": 0,
            "client_count": 0
        }
        // ... workspaces 2-8
    ]
}

switch_workspace

Switch to specified workspace (0-8). Returns current status.

// Request
{"command": "switch_workspace", "workspace": 2}

// Response
{
    "status": "ok",
    "version": "2.0.0",
    "current_workspace": 2,
    "client_count": 5
}

move_client_to_workspace

Move specific client to workspace.

{
    "command": "move_client_to_workspace",
    "window": 12345678,
    "workspace": 3
}

switch_workspace_next

Switch to the next workspace (wraps around).

{"command": "switch_workspace_next"}

// Response
{
    "status": "ok",
    "workspace": 1,
    "workspace_name": "2"
}

switch_workspace_prev

Switch to the previous workspace (wraps around).

{"command": "switch_workspace_prev"}

Layout Commands

set_layout

Set workspace layout mode. Can use string names or numeric values.

// Set layout by name ("tiling", "floating", or "monocle")
{"command": "set_layout", "layout": "floating"}

// Set layout by number (0=tiling, 1=floating, 2=monocle)
{"command": "set_layout", "layout": 1}

// Optionally specify workspace (defaults to current)
{"command": "set_layout", "layout": "monocle", "workspace": 2}

cycle_layout

Cycle to next layout mode (tiling → floating → monocle → tiling).

// Cycle current workspace
{"command": "cycle_layout"}

// Cycle specific workspace
{"command": "cycle_layout", "workspace": 3}

set_master_ratio

Set the master area ratio (0.1-0.9) for tiling layout.

// Set on current workspace
{"command": "set_master_ratio", "ratio": 0.6}

// Set on specific workspace
{"command": "set_master_ratio", "ratio": 0.55, "workspace": 2}

// Response
{
    "status": "ok",
    "workspace": 0,
    "master_ratio": 0.6
}

adjust_master_ratio

Adjust the master area ratio by a delta value.

// Increase master area by 5%
{"command": "adjust_master_ratio", "delta": 0.05}

// Decrease master area by 5%
{"command": "adjust_master_ratio", "delta": -0.05}

set_master_count

Set the number of windows in the master area (1-10).

{"command": "set_master_count", "count": 2}

// Response
{
    "status": "ok",
    "workspace": 0,
    "master_count": 2
}

adjust_master_count

Adjust the master count by a delta value.

// Add one window to master
{"command": "adjust_master_count", "delta": 1}

// Remove one window from master
{"command": "adjust_master_count", "delta": -1}

focus_next

Focus the next window in the current workspace.

{"command": "focus_next"}

// Response
{
    "status": "ok",
    "focused_window": 12345678,
    "focused_title": "Firefox"
}

focus_prev

Focus the previous window in the current workspace.

{"command": "focus_prev"}

focus_master

Focus the first window in the master area.

{"command": "focus_master"}

snap_client

Snap a window to screen edge or corner.

// Snap focused window left
{"command": "snap_client", "direction": "left"}

// Snap specific window
{"command": "snap_client", "window": 12345678, "direction": "right"}

// Directions: left, right, up, down
// Snapping is composable: left then up = top-left corner

// Response
{
    "status": "ok",
    "window": 12345678,
    "snap": {
        "horizontal": 1,
        "vertical": 0
    }
}

Keyboard Commands

key_press

Simulate key press (key down only). Use keysym (X11 keysym name) or keycode.

// By keysym name (X11 keysym names)
{"command": "key_press", "keysym": "a"}
{"command": "key_press", "keysym": "Return"}
{"command": "key_press", "keysym": "Tab"}
{"command": "key_press", "keysym": "Escape"}
{"command": "key_press", "keysym": "F1"}
{"command": "key_press", "keysym": "Control_L"}

// By keycode (hardware keycode)
{"command": "key_press", "keycode": 38}

key_release

Simulate key release (key up only).

{"command": "key_release", "keysym": "a"}
{"command": "key_release", "keycode": 38}

key_tap

Simulate a complete keypress (press + release) with optional modifiers.

// Simple key tap
{"command": "key_tap", "keysym": "a"}

// With modifiers (modifier keysym names)
{"command": "key_tap", "keysym": "c", "modifiers": ["Control_L"]}
{"command": "key_tap", "keysym": "t", "modifiers": ["Control_L", "Alt_L"]}
{"command": "key_tap", "keysym": "s", "modifiers": ["Control_L", "Shift_L"]}

// Special keys
{"command": "key_tap", "keysym": "Return"}
{"command": "key_tap", "keysym": "Tab"}
{"command": "key_tap", "keysym": "Escape"}
{"command": "key_tap", "keysym": "F1"}

Common modifier keysyms: Control_L, Control_R, Shift_L, Shift_R, Alt_L, Alt_R, Super_L, Super_R

key_type

Type a string of text. Automatically handles shift for uppercase and special characters.

{"command": "key_type", "text": "Hello, World!"}

Mouse Commands

mouse_move

Move mouse to absolute position.

{"command": "mouse_move", "x": 500, "y": 300}

mouse_move_relative

Move mouse relative to current position.

{"command": "mouse_move_relative", "dx": 10, "dy": -5}

mouse_click

Click mouse button (press + release).

// Left click at current position
{"command": "mouse_click", "button": 1}

// Right click at specific position (moves mouse first)
{"command": "mouse_click", "button": 3, "x": 100, "y": 200}

Buttons: 1=left, 2=middle, 3=right, 4=scroll up, 5=scroll down

mouse_press

Press mouse button without releasing (for drag operations).

{"command": "mouse_press", "button": 1}

mouse_release

Release mouse button.

{"command": "mouse_release", "button": 1}

mouse_scroll

Scroll mouse wheel.

// Scroll up (amount 1-100, default 1)
{"command": "mouse_scroll", "direction": "up", "amount": 3}

// Scroll down
{"command": "mouse_scroll", "direction": "down", "amount": 3}

get_mouse_position

Get current mouse position and window under cursor.

// Request
{"command": "get_mouse_position"}

// Response
{
    "status": "ok",
    "x": 500,
    "y": 300,
    "window_x": 100,
    "window_y": 50,
    "window": 12345678
}

Screenshot Commands

screenshot

Capture screenshot. Returns base64-encoded PNG.

Async Mode (Default)

By default, screenshot operations run asynchronously to avoid blocking the API. Set "async": false for synchronous behavior.

// Async (default) - returns when capture completes
{"command": "screenshot", "mode": "fullscreen"}

// Synchronous - blocks until complete
{"command": "screenshot", "mode": "fullscreen", "async": false}

Fullscreen Mode

// Request
{"command": "screenshot", "mode": "fullscreen"}

// Response
{
    "status": "ok",
    "format": "png",
    "encoding": "base64",
    "width": 1920,
    "height": 1080,
    "data": "iVBORw0KGgoAAAANSUhEUg..."
}

Active Window Mode

{"command": "screenshot", "mode": "active"}

Specific Window Mode

{"command": "screenshot", "mode": "window", "window": 12345678}

Area Mode

{
    "command": "screenshot",
    "mode": "area",
    "x": 100,
    "y": 100,
    "width": 400,
    "height": 300
}

OCR Commands

ocr

Extract text from image using OCR.

Async Mode (Default)

OCR operations run asynchronously by default since text extraction can take 1-10 seconds. Set "async": false for synchronous behavior.

// Async (default)
{"command": "ocr", "image": "...", "language": "eng"}

// Synchronous
{"command": "ocr", "image": "...", "language": "eng", "async": false}

Request/Response

// Request
{
    "command": "ocr",
    "image": "iVBORw0KGgoAAAANSUhEUg...",  // base64 PNG
    "language": "eng"                        // optional, default "eng"
}

// Response
{
    "status": "ok",
    "text": "Extracted text from image...",
    "confidence": 0.95
}

Common language codes: eng (English), deu (German), fra (French), spa (Spanish)

Notification Commands

notify

Show a desktop notification.

// Request
{
    "command": "notify",
    "summary": "Hello!",
    "body": "This is a notification message",
    "app_name": "My App",
    "timeout": 5000
}

// Response
{
    "status": "ok",
    "notification_id": 1
}

close_notification

Close a notification by ID.

{"command": "close_notification", "id": 1}

get_notifications

Get list of active notifications.

{"command": "get_notifications"}

// Response
{
    "status": "ok",
    "notifications": [
        {
            "id": 1,
            "app_name": "My App",
            "summary": "Hello!",
            "body": "This is a notification",
            "timeout": 5000,
            "urgency": 1
        }
    ]
}

System Tray Commands

get_battery_state

Get battery status information.

{"command": "get_battery_state"}

// Response
{
    "status": "ok",
    "battery": {
        "present": true,
        "charging": false,
        "percentage": 75,
        "time_remaining": 180
    }
}

get_audio_state

Get audio volume and mute status.

{"command": "get_audio_state"}

// Response
{
    "status": "ok",
    "volume": 50,
    "muted": false
}

set_audio_volume

Set audio volume (0-100).

{"command": "set_audio_volume", "volume": 75}

// Response
{
    "status": "ok",
    "volume": 75,
    "muted": false
}

toggle_audio_mute

Toggle audio mute state.

{"command": "toggle_audio_mute"}

// Response
{
    "status": "ok",
    "muted": true,
    "volume": 75
}

get_wifi_state

Get WiFi connection status.

{"command": "get_wifi_state"}

// Response
{
    "status": "ok",
    "enabled": true,
    "connected": true,
    "ssid": "MyNetwork",
    "signal_strength": 80
}

Panel Commands

get_panel_state

Get state of top and bottom panels.

{"command": "get_panel_state"}

// Response
{
    "status": "ok",
    "top_panel": {
        "enabled": true,
        "visible": true,
        "x": 0,
        "y": 0,
        "width": 1920,
        "height": 32
    },
    "bottom_panel": {
        "enabled": true,
        "visible": true,
        "x": 0,
        "y": 1048,
        "width": 1920,
        "height": 32
    }
}

show_panel

Show a panel.

{"command": "show_panel", "panel": "top"}
{"command": "show_panel", "panel": "bottom"}

hide_panel

Hide a panel.

{"command": "hide_panel", "panel": "top"}

toggle_panel

Toggle panel visibility.

{"command": "toggle_panel", "panel": "bottom"}

AI Commands

ai_is_available

Check if AI features are available (API key configured).

{"command": "ai_is_available"}

// Response
{
    "status": "ok",
    "available": true,
    "model": "google/gemini-2.0-flash-exp:free"
}

ai_command

Send a command to the AI assistant. Async by default.

// Request
{
    "command": "ai_command",
    "prompt": "What windows are open?",
    "async": true
}

// Response (when complete)
{
    "status": "ok",
    "response": "You have 3 windows open: Firefox, Terminal, and VS Code..."
}

exa_is_available

Check if Exa semantic search is available.

{"command": "exa_is_available"}

// Response
{
    "status": "ok",
    "available": true
}

exa_search

Perform semantic web search using Exa. Async by default.

// Request
{
    "command": "exa_search",
    "query": "how to configure nginx reverse proxy",
    "async": true
}

// Response
{
    "status": "ok",
    "results": [
        {
            "title": "NGINX Reverse Proxy Configuration",
            "url": "https://example.com/nginx-guide",
            "snippet": "Learn how to configure NGINX as a reverse proxy...",
            "score": 0.95
        }
    ]
}

News Commands

get_news

Get news articles from the news ticker.

{"command": "get_news"}

// Response
{
    "status": "ok",
    "current_article": 0,
    "article_count": 10,
    "fetching": false,
    "has_error": false,
    "articles": [
        {
            "title": "Breaking News...",
            "content": "Article content...",
            "link": "https://example.com/news/1",
            "author": "John Doe",
            "sentiment": 0,
            "sentiment_score": 0.5
        }
    ]
}

news_next

Navigate to next news article.

{"command": "news_next"}

// Response
{
    "status": "ok",
    "current_article": 1,
    "title": "Next article title..."
}

news_prev

Navigate to previous news article.

{"command": "news_prev"}

news_open

Open current news article in browser.

{"command": "news_open"}

// Response
{
    "status": "ok",
    "link": "https://example.com/news/1"
}

Demo/Tutorial Commands

start_demo

Start the automated demo mode.

{"command": "start_demo"}

stop_demo

Stop the demo mode.

{"command": "stop_demo"}

get_demo_state

Get current demo mode state.

{"command": "get_demo_state"}

// Response
{
    "status": "ok",
    "active": true,
    "phase": 2,
    "phase_name": "DEMO_WORKSPACES",
    "step": 3
}

start_tutorial

Start the interactive tutorial.

{"command": "start_tutorial"}

stop_tutorial

Stop the tutorial.

{"command": "stop_tutorial"}

get_tutorial_state

Get current tutorial state.

{"command": "get_tutorial_state"}

// Response
{
    "status": "ok",
    "active": true
}

Configuration Commands

get_config

Get configuration values. Get a specific key or all config.

// Get specific key
{"command": "get_config", "key": "terminal"}

// Response
{
    "status": "ok",
    "value": "xfce4-terminal"
}

// Get all config
{"command": "get_config"}

// Response
{
    "status": "ok",
    "config": {
        "terminal": "xfce4-terminal",
        "launcher": "dmenu_run",
        "focus_mode": "click",
        "border_width": 0,
        "panel_height": 32,
        "gap": 0,
        "ai_enabled": true,
        "fade_speed": 0.5,
        "fade_intensity": 1.0
        ...
    }
}

reload_config

Reload configuration from file.

{"command": "reload_config"}

// Response
{
    "status": "ok"
}

get_keybindings

Get list of all keyboard shortcuts.

{"command": "get_keybindings"}

// Response
{
    "status": "ok",
    "keybindings": [
        {
            "key": "t",
            "modifiers": "ctrl+alt",
            "description": "Open terminal"
        },
        {
            "key": "F4",
            "modifiers": "alt",
            "description": "Close focused window"
        }
        ...
    ]
}

Event Subscription

DWN supports real-time event streaming over WebSocket. Subscribe to events to receive notifications about window actions, workspace changes, input events, and more.

list_events

Get list of all available event types.

// Request
{"command": "list_events"}

// Response
{
    "status": "ok",
    "events": [
        "window_created",
        "window_destroyed",
        "window_focused",
        "window_unfocused",
        "window_moved",
        "window_resized",
        "window_minimized",
        "window_restored",
        "window_maximized",
        "window_unmaximized",
        "window_fullscreen",
        "window_unfullscreen",
        "window_floating",
        "window_unfloating",
        "window_title_changed",
        "window_raised",
        "window_lowered",
        "workspace_switched",
        "workspace_window_added",
        "workspace_window_removed",
        "workspace_layout_changed",
        "workspace_master_ratio_changed",
        "workspace_master_count_changed",
        "workspace_arranged",
        "layout_changed",
        "key_pressed",
        "key_released",
        "shortcut_triggered",
        "mouse_moved",
        "mouse_button_pressed",
        "mouse_button_released",
        "drag_started",
        "drag_ended",
        "show_desktop_toggled",
        "notification_shown",
        "notification_closed"
    ]
}

subscribe

Subscribe to specific events or all events.

// Subscribe to specific events
{"command": "subscribe", "events": ["window_focused", "window_created"]}

// Subscribe to all events
{"command": "subscribe", "all": true}

// Response
{
    "status": "ok",
    "subscribed": ["window_focused", "window_created"]
}

unsubscribe

Unsubscribe from specific events or all events.

// Unsubscribe from specific events
{"command": "unsubscribe", "events": ["window_focused"]}

// Unsubscribe from all events
{"command": "unsubscribe", "all": true}

// Response
{"status": "ok"}

Event Message Format

When subscribed, events are pushed to the client as JSON messages:

// Window focus event
{
    "type": "event",
    "event": "window_focused",
    "data": {
        "window": 12345678,
        "title": "Firefox",
        "previous_window": 87654321
    }
}

// Window moved event
{
    "type": "event",
    "event": "window_moved",
    "data": {
        "window": 12345678,
        "old_x": 0,
        "old_y": 32,
        "new_x": 100,
        "new_y": 100
    }
}

// Workspace switched event
{
    "type": "event",
    "event": "workspace_switched",
    "data": {
        "old_workspace": 0,
        "new_workspace": 2
    }
}

// Keyboard shortcut triggered
{
    "type": "event",
    "event": "shortcut_triggered",
    "data": {
        "name": "Return",
        "description": "Open terminal"
    }
}

// Notification shown
{
    "type": "event",
    "event": "notification_shown",
    "data": {
        "id": 1,
        "summary": "New Message",
        "body": "You have a new message"
    }
}

// Fade speed changed
{
    "type": "event",
    "event": "fade_speed_changed",
    "data": {
        "old_speed": 0.5,
        "new_speed": 1.0
    }
}

// Fade intensity changed
{
    "type": "event",
    "event": "fade_intensity_changed",
    "data": {
        "old_intensity": 1.0,
        "new_intensity": 0.8
    }
}

Event Types Reference

Event Description Data Fields
window_created New window managed window, title, class, workspace
window_destroyed Window closed window, title, workspace
window_focused Window received focus window, title, previous_window
window_unfocused Window lost focus window, title
window_moved Window position changed window, old_x, old_y, new_x, new_y
window_resized Window size changed window, old_width, old_height, new_width, new_height
window_minimized Window minimized window
window_restored Window restored from minimized window
window_maximized Window maximized/unmaximized window, maximized
window_fullscreen Fullscreen toggled window, fullscreen
window_floating Floating mode toggled window, floating
window_title_changed Window title updated window, old_title, new_title
workspace_switched Active workspace changed old_workspace, new_workspace
workspace_layout_changed Workspace layout changed workspace, old_layout, new_layout
key_pressed Key pressed keycode, keysym, modifiers
shortcut_triggered Keyboard shortcut executed name, description
mouse_button_pressed Mouse button pressed button, x, y
drag_started Window drag/resize started window, is_resize
drag_ended Window drag/resize ended window, is_resize
show_desktop_toggled Show desktop mode toggled shown
notification_shown Notification displayed id, summary, body
notification_closed Notification closed id
fade_speed_changed Fade animation speed changed old_speed, new_speed
fade_intensity_changed Fade glow intensity changed old_intensity, new_intensity
window_snapped Window snapped to position window, horizontal, vertical
audio_volume_changed System audio volume changed old_volume, new_volume
audio_mute_toggled System audio mute toggled muted
panel_visibility_changed Panel shown or hidden panel, visible
config_reloaded Configuration reloaded (none)
ai_response_received AI command completed prompt, response, success
exa_search_completed Exa search completed query, result_count, success
news_article_changed News ticker article changed old_index, new_index, title
demo_started Demo mode started (none)
demo_stopped Demo mode stopped (none)
demo_phase_changed Demo phase changed phase, phase_name
tutorial_started Tutorial mode started (none)
tutorial_stopped Tutorial mode stopped (none)

System Commands

get_status

Get DWN status information.

// Request
{"command": "get_status"}

// Response
{
    "status": "ok",
    "version": "2.0.0",
    "current_workspace": 0,
    "client_count": 5
}

get_screen_info

Get screen and monitor information.

// Request
{"command": "get_screen_info"}

// Response
{
    "status": "ok",
    "screen_width": 1920,
    "screen_height": 1080,
    "screen": 0,
    "monitor_count": 1,
    "monitors": [
        {
            "index": 0,
            "x": 0,
            "y": 0,
            "width": 1920,
            "height": 1080,
            "primary": true
        }
    ],
    "usable_area": {
        "x": 0,
        "y": 32,
        "width": 1920,
        "height": 1048
    }
}

run_command

Spawn a process asynchronously.

// Request
{"command": "run_command", "exec": "firefox"}

// Response
{"status": "launched"}

show_desktop

Toggle show desktop mode. Optionally set explicit state.

// Toggle
{"command": "show_desktop"}

// Set explicit state
{"command": "show_desktop", "state": true}

// Response
{
    "status": "ok",
    "desktop_shown": true
}

get_fade_settings

Get current fade effect settings (speed and intensity).

// Request
{"command": "get_fade_settings"}

// Response
{
    "status": "ok",
    "fade_speed": 0.5,
    "fade_intensity": 1.0
}

set_fade_speed

Set fade animation speed (0.1 - 3.0, where 1.0 is normal speed).

// Request
{"command": "set_fade_speed", "speed": 1.5}

// Response
{
    "status": "ok",
    "fade_speed": 1.5
}

set_fade_intensity

Set fade glow intensity (0.0 - 1.0, where 1.0 is full intensity).

// Request
{"command": "set_fade_intensity", "intensity": 0.8}

// Response
{
    "status": "ok",
    "fade_intensity": 0.8
}

Error Responses

All commands may return errors:

{
    "status": "error",
    "message": "Window not found"
}

{
    "status": "error",
    "message": "Invalid parameter: workspace must be 0-8"
}

{
    "status": "error",
    "message": "Unknown command: invalid_command"
}