Python library for controlling the i3 window manager and sway compositor through their IPC interface
—
Complete command execution functionality for sending commands to i3/sway and handling responses. Supports all i3/sway commands with detailed response handling and error reporting.
def command(self, payload: str) -> List[CommandReply]:
"""
Execute i3/sway commands and get detailed response.
Parameters:
- payload: str, command string to execute (can contain multiple commands separated by semicolons)
Returns:
List[CommandReply]: response for each command executed
"""def send_tick(self, payload: str = "") -> TickReply:
"""
Send a tick event with optional payload data.
Parameters:
- payload: str, optional data to include with the tick event
Returns:
TickReply: confirmation of tick event processing
"""class CommandReply:
"""Response from command execution."""
success: bool # Whether the command executed successfully
error: str # Error message if command failed (None if successful)
ipc_data: dict # Raw IPC response dataclass TickReply:
"""Response from tick event transmission."""
success: bool # Whether tick was processed successfully
ipc_data: dict # Raw IPC response data# Available on Con objects for targeted command execution
def command(self, command: str) -> List[CommandReply]:
"""
Execute command on this specific container.
Parameters:
- command: str, command to execute (container will be implicitly focused first)
Returns:
List[CommandReply]: command execution results
"""
def command_children(self, command: str) -> List[CommandReply]:
"""
Execute command on all direct child containers.
Parameters:
- command: str, command to execute on each child container
Returns:
List[CommandReply]: execution results for each child
"""# Window management commands
i3.command('focus left')
i3.command('focus right')
i3.command('focus up')
i3.command('focus down')
i3.command('focus parent')
i3.command('focus child')
# Window movement
i3.command('move left')
i3.command('move right')
i3.command('move up')
i3.command('move down')
i3.command('move container to workspace 2')
i3.command('move workspace to output HDMI-A-1')
# Layout commands
i3.command('split horizontal')
i3.command('split vertical')
i3.command('layout stacking')
i3.command('layout tabbed')
i3.command('layout toggle split')
# Window state
i3.command('fullscreen toggle')
i3.command('floating toggle')
i3.command('sticky toggle')
# Workspace commands
i3.command('workspace 1')
i3.command('workspace next')
i3.command('workspace prev')
i3.command('workspace back_and_forth')
i3.command('rename workspace to "new-name"')
# Application launching
i3.command('exec firefox')
i3.command('exec --no-startup-id notify-send "Hello"')
# Container operations
i3.command('kill')
i3.command('mark mymark')
i3.command('unmark mymark')
i3.command('[title="Firefox"] focus')
# i3 control
i3.command('reload')
i3.command('restart')
i3.command('exit')
# Multiple commands
result = i3.command('workspace 2; exec firefox; split horizontal')
for i, reply in enumerate(result):
print(f"Command {i+1}: {'success' if reply.success else f'error: {reply.error}'}")# Check command execution results
result = i3.command('invalid_command')
reply = result[0]
if reply.success:
print("Command executed successfully")
else:
print(f"Command failed: {reply.error}")
# Handle multiple command results
results = i3.command('workspace 1; split horizontal; exec nonexistent-app')
for i, reply in enumerate(results):
if not reply.success:
print(f"Command {i+1} failed: {reply.error}")
# Container-specific command execution with error handling
focused = i3.get_tree().find_focused()
if focused:
results = focused.command('layout tabbed')
if results[0].success:
print(f"Changed layout for container {focused.id}")
else:
print(f"Failed to change layout: {results[0].error}")# Send tick with payload for coordination
tick_result = i3.send_tick("script-completed")
if tick_result.success:
print("Tick sent successfully")
# Subscribe to tick events to receive the tick
def on_tick(i3, event):
print(f"Received tick: {event.payload}")
if event.payload == "script-completed":
print("Script coordination completed")
i3.on(Event.TICK, on_tick)
# Send tick from another process/script
i3.send_tick("processing-started")
# ... do work ...
i3.send_tick("processing-finished")Install with Tessl CLI
npx tessl i tessl/pypi-i3ipc