Skip to main content
Mango includes an IPC (Inter-Process Communication) system that allows external programs to interact with the compositor. This enables scripting, automation, custom tools, and integration with other applications.

Overview

The IPC system provides:
  • Query Compositor State: Get information about windows, tags, layouts, and monitors
  • Send Commands: Control the compositor programmatically
  • Scripting Support: Build custom automation and workflows
  • External Tools: Integrate with status bars, launchers, and utilities
  • Real-time Updates: React to compositor events

IPC Protocol

Mango’s IPC is based on the dwl-ipc protocol, providing a stable interface for external communication.

Protocol File

The IPC protocol is defined in:
src/ext-protocol/dwl-ipc.h
This protocol allows clients to:
  • Subscribe to compositor events
  • Query current state
  • Send commands to the compositor

Using IPC

IPC Socket

Mango creates an IPC socket that clients connect to for communication. The socket location typically follows XDG standards:
# Socket location (typical)
$XDG_RUNTIME_DIR/mango-ipc.sock

IPC Clients

To interact with Mango via IPC, you need an IPC client:
  1. Direct Socket Communication: Write your own client using Unix sockets
  2. Existing Tools: Use compatible tools from dwl ecosystem
  3. Status Bar Integration: Many status bars support dwl-ipc protocol

IPC Commands

While specific command syntax requires checking the protocol definition, typical IPC capabilities include:

Query Commands

List Windows

Get information about all open windows

Current Tag

Query which tag is currently active

Layout Info

Get current layout name and configuration

Monitor Status

Query connected monitors and their state

Control Commands

Change Layout

Switch to a specific layout programmatically

Focus Window

Focus a specific window by ID

Move Window

Move windows between tags or monitors

Execute Actions

Trigger compositor actions from external scripts

Status Bar Integration

Waybar

Waybar can integrate with Mango via IPC to display compositor information:
{
  "modules-left": ["wlr/workspaces"],
  "wlr/workspaces": {
    "format": "{name}",
    "on-click": "activate"
  }
}
Specific Waybar module configuration for Mango may require the wlr/workspaces module or a dwl-specific module. Check Waybar documentation for details.

Other Status Bars

Status bars with dwl-ipc support:
  • Waybar: Via wlr/workspaces or custom modules
  • eww: Via custom IPC scripts
  • AGS: Via JavaScript IPC bindings
  • yambar: Via custom IPC integration

Scripting with IPC

Example Use Cases

Switch layouts based on time of day, number of windows, or other conditions.
#!/bin/bash
# Switch to monocle for single window
window_count=$(mango-ipc-client window-count)
if [ "$window_count" -eq 1 ]; then
  mango-ipc-client set-layout monocle
fi
Create custom window management commands.
#!/bin/bash
# Move all Firefox windows to tag 2
mango-ipc-client list-windows | \
  grep "firefox" | \
  while read window_id; do
    mango-ipc-client move-window "$window_id" 2
  done
Automatically adjust layout when monitor configuration changes.
#!/bin/bash
# Change layout for vertical monitor
monitor=$(mango-ipc-client active-monitor)
if [[ "$monitor" == *"vertical"* ]]; then
  mango-ipc-client set-layout vertical_tile
fi
Feed compositor state to other applications.
#!/bin/bash
# Update external display with current tag
while true; do
  tag=$(mango-ipc-client current-tag)
  echo "Tag: $tag" > /tmp/mango-status
  sleep 1
done

Building IPC Clients

Socket Communication

IPC clients connect to Mango’s Unix socket:
import socket
import json

def send_ipc_command(command):
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    sock.connect("/run/user/1000/mango-ipc.sock")
    
    # Send command (protocol-specific format)
    sock.send(json.dumps(command).encode())
    
    # Receive response
    response = sock.recv(4096)
    sock.close()
    
    return json.loads(response)

# Query current layout
layout = send_ipc_command({"type": "query", "request": "layout"})
print(f"Current layout: {layout['name']}")

Protocol Details

The example above is illustrative. Actual IPC protocol requires:
  • Correct message format (binary or text-based)
  • Proper protocol headers
  • Event subscription mechanism
Refer to src/ext-protocol/dwl-ipc.h for exact protocol specification.

Language Bindings

Consider creating language bindings for easier IPC usage:
  • Python: High-level wrapper around socket communication
  • JavaScript: For integration with AGS or other JS tools
  • Shell Scripts: Simple wrapper scripts for common operations
  • Rust/Go: Type-safe bindings for robust tools

IPC Event Subscription

IPC clients can subscribe to compositor events:

Event Types

window_created
event
Fired when a new window is opened
window_closed
event
Fired when a window is closed
tag_changed
event
Fired when active tag changes
layout_changed
event
Fired when layout is switched
focus_changed
event
Fired when window focus changes

Subscribing to Events

// Pseudo-code for event subscription
ipc_client_subscribe(client, EVENT_TAG_CHANGED);

while (true) {
    event = ipc_client_wait_event(client);
    if (event.type == EVENT_TAG_CHANGED) {
        printf("Switched to tag %d\n", event.tag_id);
    }
}

Integration Examples

Custom Tag Switcher

Build a graphical tag switcher:
#!/bin/bash
# rofi-based tag switcher using IPC

# Get list of tags with windows
tags=$(mango-ipc-client list-tags-with-windows)

# Show in rofi
selected=$(echo "$tags" | rofi -dmenu -p "Switch to tag:")

# Switch to selected tag
if [ -n "$selected" ]; then
  tag_id=$(echo "$selected" | cut -d: -f1)
  mango-ipc-client switch-tag "$tag_id"
fi

Window Selector

Create a window selector that works across all tags:
#!/bin/bash
# Select and focus any window via rofi

# Get all windows with titles
windows=$(mango-ipc-client list-windows-with-titles)

# Select window
selected=$(echo "$windows" | rofi -dmenu -p "Focus window:")

# Focus selected window
if [ -n "$selected" ]; then
  window_id=$(echo "$selected" | cut -d: -f1)
  mango-ipc-client focus-window "$window_id"
fi

Layout Indicator

Display current layout in status bar:
#!/bin/bash
# Output current layout for status bar

while true; do
  layout=$(mango-ipc-client current-layout)
  echo "{\"text\": \"$layout\", \"class\": \"layout\"}"
  sleep 1
done

IPC Security

Socket Permissions

The IPC socket is created with restricted permissions:
  • Only accessible to the user running Mango
  • Located in user-specific runtime directory
  • Protected by filesystem permissions

Trusted Clients

IPC allows full control over the compositor:
Any process that can connect to the IPC socket can control Mango. Ensure only trusted programs have access.

Best Practices

  • Validate input in IPC scripts
  • Avoid running untrusted IPC clients
  • Monitor IPC usage if security is a concern
  • Use IPC for automation, not as a workaround for missing features

Development and Documentation

IPC Protocol Reference

For detailed protocol documentation:
  1. Check the Mango wiki for IPC guides
  2. Review src/ext-protocol/dwl-ipc.h for protocol details
  3. Examine dwl-ipc compatible tools for implementation examples
  4. Join the Mango Discord for community support

Contributing IPC Tools

Share your IPC tools with the community:
  • Create GitHub repositories for reusable tools
  • Document IPC command usage
  • Share scripts in community channels
  • Contribute to IPC client libraries

Build docs developers (and LLMs) love