Skip to content
Waxed Display Server
← Back to Docs

waxedctl

waxedctl - Waxed Compositor Control Tool

Overview

waxedctl is the command-line interface for controlling and managing the Waxed display server. It communicates with the running compositor via a Unix domain socket, allowing you to manage plugins, modify properties, and invoke plugin APIs at runtime.

Key capabilities:

  • Load and unload plugins dynamically
  • Query plugin status and information
  • Modify plugin properties via YAML syntax
  • Invoke plugin-provided API calls
  • Query compositor status

Installation and Location

waxedctl is built as part of the Waxed project and installed to the system binary directory. After building Waxed, the tool is available as:

waxedctl

The installed binary location depends on your CMake configuration, but typically installs to:

  • /usr/local/bin/waxedctl (default)
  • /usr/bin/waxedctl (if CMAKE_INSTALL_PREFIX=/usr)

Socket Communication

waxedctl communicates with the Waxed compositor via a Unix domain socket. The socket location is determined by the following priority:

  1. Environment variable: XDG_RUNTIME_DIR (recommended)

    • Default path: $XDG_RUNTIME_DIR/waxed-ipc.sock
  2. Fallback location: If XDG_RUNTIME_DIR is not set

    • Path: /tmp/waxed-<uid>.sock
    • Where <uid> is your user ID
  3. Manual override: Use the -s or --socket option

    waxedctl -s /custom/path/socket.sock plugin list

Connection Requirements

  • The Waxed compositor must be running
  • The socket file must exist
  • You must have read/write permissions on the socket

Command Syntax

waxedctl uses a hierarchical command structure with subcommands:

waxedctl [global-options] <subcommand> [subcommand-options] [arguments]

Global Options

OptionShortDescription
--socket-sSpecify custom IPC socket path
--help-hShow help message
--version-vShow version information

Subcommands

waxedctl organizes commands into logical groups:

waxedctl

plugin

property

api

status

list: List all loaded plugins

load: Load a plugin

unload: Unload a plugin

show: Make a plugin visible

set: Set a property value

get: Get a property value

list: List all properties

list: List registered APIs

name: Execute an API call

Query compositor status

Available Commands

Plugin Management

List Plugins

Display all currently loaded plugins:

waxedctl plugin list

Example output:

Loaded plugins:
- desktop
- loginscreen
- background

Load Plugin

Load a plugin by name:

waxedctl plugin load <name>

Example:

waxedctl plugin load loginscreen

Unload Plugin

Unload a plugin by name:

waxedctl plugin unload <name>

Example:

waxedctl plugin unload loginscreen

Show Plugin

Make a plugin visible (bring it to the foreground):

waxedctl plugin show <name>

Example:

waxedctl plugin show desktop

Property Manipulation

Properties are stored as YAML configurations within plugins. The property commands allow you to modify these configurations at runtime.

Set Property

Set a property value on a plugin:

waxedctl property set <plugin> -y <key>:<value>

Format: The -y flag takes a colon-separated key:value pair. For nested keys, use additional colons.

Examples:

# Set background image
waxedctl property set loginscreen -y background:/path/to/image.jpg

# Set nested property
waxedctl property set desktop -y opacity:0.8

# Set multiple-level nested property
waxedctl property set plugin -y section:subsection:value

Get Property

Query a property value from a plugin:

waxedctl property get <plugin> -y <key>

Example:

waxedctl property get loginscreen -y background

List Properties

List all properties of a plugin:

waxedctl property list <plugin> [-y <namespace>]

The -y flag specifies the namespace (defaults to “yaml”).

Example:

waxedctl property list loginscreen

API Operations

Plugins can register API functions that can be invoked via waxedctl.

List APIs

Display all registered API calls:

waxedctl api list

Example output:

Registered APIs:
- surface_create <x> <y> <width> <height>
- surface_move <id> <x> <y>
- surface_resize <id> <width> <height>
- layer_list

Execute API Call

Invoke a plugin API:

waxedctl api <name> [args...]

Examples:

# Create a surface
waxedctl api surface_create 100 100 800 600

# List layers
waxedctl api layer_list

# Move a surface
waxedctl api surface_move 5 200 150

Status Query

Query the compositor status:

waxedctl status

Example output:

Waxed Compositor Status
Version: 1.0.0
Uptime: 2 hours 15 minutes
Active plugins: 3

Response Format

waxedctl receives responses from the compositor in the following text-based protocol format:

<status_code>\n
<message>\n
[optional data lines...]

Status Codes

CodeNameDescription
0SuccessCommand completed successfully
1ErrorGeneral error occurred
2NotFoundRequested resource not found
3InvalidCommandCommand syntax is invalid
4PermissionDeniedInsufficient permissions

Response Examples

Success response:

0
Plugin loaded successfully
desktop: active

Error response:

2
Plugin not found

Error Handling

waxedctl provides detailed error messages for common failure scenarios:

Connection Errors

Failed to connect to socket at /run/user/1000/waxed-ipc.sock
Connection refused

Possible reasons:
  - Waxed compositor is not running
  - Socket file does not exist
  - Insufficient permissions

Resolution:

  • Verify Waxed is running: ps aux | grep waxed
  • Check socket exists: ls -la $XDG_RUNTIME_DIR/waxed-ipc.sock
  • Verify permissions: The socket should be readable/writable by your user

Command Errors

1
Plugin 'loginscreen' not found

Resolution:

  • Check available plugins: waxedctl plugin list
  • Verify plugin name spelling

Property Errors

1
Invalid property format. Use 'key:value' syntax.

Resolution:

  • Ensure you’re using the correct key:value format with the -y flag
  • Check that the property exists in the plugin’s configuration

Example Usage Sessions

Session 1: Basic Plugin Management

# List current plugins
$ waxedctl plugin list
Loaded plugins:
- desktop

# Load the loginscreen plugin
$ waxedctl plugin load loginscreen
Plugin loaded successfully

# Verify it's loaded
$ waxedctl plugin list
Loaded plugins:
- desktop
- loginscreen

Session 2: Configuring Properties

# Change the login screen background
$ waxedctl property set loginscreen -y background:/usr/share/backgrounds/nature.jpg
Property updated successfully

# Verify the change
$ waxedctl property get loginscreen -y background
/usr/share/backgrounds/nature.jpg

# List all properties
$ waxedctl property list loginscreen
Properties in 'yaml' namespace:
background: /usr/share/backgrounds/nature.jpg
opacity: 1.0
blur_radius: 20

Session 3: API Interaction

# List available APIs
$ waxedctl api list
Registered APIs:
- surface_create <x> <y> <width> <height>
- layer_list

# Create a new surface
$ waxedctl api surface_create 100 100 800 600
Surface created with ID: 42

# List layers
$ waxedctl api layer_list
Layer 0: background
Layer 1: desktop
Layer 2: surfaces

Session 4: Dynamic Reloading

# Unload a plugin
$ waxedctl plugin unload background
Plugin unloaded successfully

# Reload it
$ waxedctl plugin load background
Plugin loaded successfully

# Make it visible
$ waxedctl plugin show background
Plugin is now visible

Integration with Compositor

IPC Architecture

Waxed Core

waxedctl

User executes

Core processes and responds

Unix Domain Socket

CLI Parser

Command Builder

Response Parser

IPC Handler

Plugin Manager

Property Store

User

Core

Command Flow

1. User executes command waxedctl plugin load loginscreen
2. CLI11 parses arguments

Subcommand: plugin

Action: load

Argument: loginscreen

3. Build IPC command plugin:loginscreen load
4. Connect to socket XDG_RUNTIME_DIR waxed-ipc.sock
5. Send command send sock_fd plugin:loginscreen load
6. Receive response 0 Plugin loaded successfully
7. Parse and display

Status: 0 Success

Message: Plugin loaded successfully

Protocol Details

The IPC protocol uses text-based commands for human-readability:

CommandProtocol StringDescription
List pluginslistGet all loaded plugins
Load pluginplugin:<name> loadLoad specified plugin
Unload pluginplugin:<name> unloadUnload specified plugin
Show pluginplugin:<name> showMake plugin visible
Set propertyplugin:<name> yaml:<key>:<value>Set property value
Get propertyplugin:<name> yaml:get:<key>Get property value
List propertiesplugin:<name> yaml:listList all properties
API listapi listList registered APIs
API callapi <name> [args...]Execute API function
StatusstatusQuery compositor status
HelphelpShow help text

Plugin Integration

Plugins integrate with waxedctl through the core API:

  1. Registration: Plugins register themselves with the PluginManager
  2. Properties: Each plugin has a YAML property store
  3. API Functions: Plugins can register callable API functions
  4. Lifecycle: Plugins can be loaded/unloaded at runtime

Security Considerations

  • Socket permissions: Only the user running Waxed can access the socket
  • No authentication: The tool assumes local access equates to authorized use
  • Property validation: Plugins should validate property values before applying

Sequence Diagrams

Complete Command Flow

Waxed CompositorwaxedctlUser ShellWaxed CompositorwaxedctlUser Shell$ waxedctl plugin listConnect to socketSend: "list"Query plugins from managerRecv: "0\nLoaded plugins..."Loaded plugins: desktop, loginscreen

Socket Location Resolution

Provided

Not provided

Set

Not set

Start

Check --socket flag

Use specified path

Check XDG_RUNTIME_DIR

Use XDG_RUNTIME_DIR/waxed-ipc.sock

Use fallback /tmp/waxed-uid.sock

Connect

Property Set Command Breakdown

User Command

Parsed by compositor

plugin_name: loginscreen

property_namespace: yaml

property_key: background

property_value: /path/to/image.jpg

Generated IPC Command

plugin:loginscreen

yaml:background:path/to/image.jpg

waxedctl property set loginscreen

-y background:path/to/image.jpg

Plugin name: loginscreen

YAML key:value

Key: background

Value: /path/to/image.jpg

Tips and Best Practices

  1. Check socket location if commands fail:

    echo $XDG_RUNTIME_DIR/waxed-ipc.sock
    ls -la $XDG_RUNTIME_DIR/waxed-ipc.sock
  2. Use tab completion - Many shells support completion for waxedctl subcommands

  3. Query before modifying - Always check current values with property get before setting new ones

  4. List available APIs - Use api list to see what functions are available before calling them

  5. Test property changes - Some plugins reload configuration on change, others may require a reload

  6. Check logs - If commands fail, check the Waxed compositor logs for detailed error messages

Troubleshooting

SymptomCauseSolution
”Failed to connect”Compositor not runningStart Waxed compositor
”Socket file does not exist”Wrong socket pathUse -s flag with correct path
”Permission denied”Wrong userRun as same user as compositor
”Plugin not found”Plugin not loadedUse plugin load first
”Property not found”Invalid keyUse property list to find valid keys
”Invalid command syntax”Wrong argument formatCheck command syntax with -h