Skip to main content

Python bindings for communicating with the Sway window manager over its IPC socket.

Project description

swayipc - Interact with Sway

A fully-typed package for interacting with the Sway window manager via its IPC connection. Run man 7 sway for more information on its IPC protocol. (docs)

Goals

  • Low-level interface for interacting with the IPC socket (See section Low-level)
  • A model of the Sway IPC objects and their main commands (See section Commands)
  • Maintain a fully-typed high-level data model
  • Example-driven documentation as a Sphinx project
  • A data model allowing actions such as Workspace(name="dev").focus()
  • A typed command builder. low priority, but it'd be handy.

[!NOTE] This package was started as a precursor to a different project that I'm working on, and originally spawned as a way for me to learn more about the IPC. As such, it's very likely to experience significant changes until its first stable release.

Install

pip install swayipc

Commands

run_command(...)

Runs a sway command, or a series of sway commands. Each command, separated by a comma, will have its own CommandResult.

REPLY: An array of objects corresponding to each command that was parsed. Each object has the property success, which is a boolean indicating whether the command was successful. The object may also contain the properties error and parse_error. The error property is a human readable error message while parse_error is a boolean indicating whether the reason the command failed was because the command was unknown or not able to be parsed. (docs)

>>> import swayipc
>>> swayipc.run_command('floating toggle')
[CommandResult(success=True)]
>>> swayipc.run_command('floating toggle, fake command')
[
    CommandResult(success=True),
    CommandResult(
       error="Unknown/invalid command 'fake'",
       parse_error=True,
       success=False
    )
]

get_workspaces()

Retrieves the list of workspaces.

REPLY: The reply is an array of objects corresponding to each workspace. (docs)

>>> import swayipc
>>> ws = swayipc.get_workspaces()
>>> ws[0]
Workspace(
  border='none',
  current_border_width=0,
  deco_rect=Rect(height=0, width=0, x=0, y=0),
  floating_nodes=[],
  focus=[27],
  focused=False,
  fullscreen_mode=1,
  geometry=Rect(height=0, width=0, x=0, y=0),
  id=28,
  layout='splith', 
  marks=[],
  name='3',
  nodes=[],
  num=3,
  orientation='horizontal',
  output='DSI-1',
  percent=None,
  rect=Rect(height=800, width=1280, x=0, y=0),
  representation='H[appname]',
  sticky=False,
  type='workspace',
  urgent=False, 
  visible=False, 
  window=None,
  window_rect=Rect(height=0, width=0, x=0, y=0),
)

subscribe(events)

Subscribe this IPC connection to the event types specified in the message payload. The payload should be a valid JSON array of events. (docs)

This function returns a generator that yields each event recieved from the IPC socket.

get_outputs()

Retrieve the list of outputs.

REPLY: An array of objects corresponding to each output. (docs)

>>> import swayipc
>>> swayipc.get_outputs()
[
   Output(
     active=True, 
     adaptive_sync_status='disabled', 
     border='none', 
     current_border_width=0, 
     current_mode=OutputMode(
       height=1280,
       refresh=59928,
       width=800
    ),
    current_workspace='4',
    deco_rect=Rect(height=0, width=0, x=0, y=0),
    dpms=True, 
    floating_nodes=[], 
    focus=[314, 28, 310, 304], 
    focused=True, 
    fullscreen_mode=0, 
    geometry=Rect(height=0, width=0, x=0, y=0), 
    id=3, 
    layout='output', 
    make='Unknown', 
    marks=[], 
    max_render_time=0, 
    model='Unknown', 
    modes=[
      OutputMode(height=1280, refresh=59928.0, width=800),
      OutputMode(height=1920, refresh=60000.0, width=1200)
    ],
    name='DSI-1', 
    nodes=[], 
    non_desktop=False, 
    orientation='none', 
    percent=1.0, 
    power=True, 
    primary=False, 
    rect=Rect(height=800, width=1280, x=0, y=0),
    scale=1.0,
    scale_filter='nearest',
    serial='Unknown', 
    sticky=False,
    subpixel_hinting=<Hinting.RGB: 'rgb'>,
    transform=<OutputTransform.T_90: '90'>,
    type='output',
    urgent=False,
    window=None,
    window_rect=Rect(height=0, width=0, x=0, y=0)
  )
]

get_tree()

Get the full view tree. Each tree object can be one of: RootNode, ContainerNode, OutputNode, or ViewNode.

REPLY: An array of objects that represent the current tree. (docs)

get_marks()

Retrieve the currently set marks.

REPLY: An array of marks current set. Since each mark can only be set for one container, this is a set so each value is unique and the order is undefined. (docs)

get_bar_config(bar_id?)

Without a bar_id specified

Retrieves the list of configured bar IDs.

REPLY: An array of bar IDs, which are strings (docs)]

>>> import python
>>> swayipc.get_bar_config()
['bar-0', 'bar-primary']

With a bar_id specified

When sent with a bar ID as the payload, this retrieves the config associated with the specified by the bar ID in the payload. This is used by swaybar, but could also be used for third party bars.

REPLY: An object that represents the configuration for the bar with the bar ID sent as the payload. ^[https://man.archlinux.org/man/sway-ipc.en#6._GET_BAR_CONFIG_(WITH_A_PAYLOAD)]

>>> import python
>>> swayipc.get_bar_config('bar-0')
BarConfig(
  bar_height=0,
  binding_mode_indicator=True,
  colors=dict(...),
  font='Compagnon 10',
  gaps=Gaps(bottom=0, left=0, right=0, top=0), 
  hidden_state='hide',
  id='bar-0',
  mode='dock', 
  pango_markup=True, 
  position='bottom',
  status_command=None,
  status_edge_padding=3,
  status_padding=1,
  strip_workspace_name=False,
  strip_workspace_numbers=False,
  tray_padding=2,
  verbose=False,
  workspace_buttons=True,
  workspace_min_width=0,
  wrap_scroll=False
)

get_version()

Retrieve version information about the sway process (docs)

>>> import swayipc
>>> swayipc.get_version()
{
   'human_readable': '1.8.1',
   'variant': 'sway',
   'major': 1,
   'minor': 8,
   'patch': 1,
   'loaded_config_file_name': '/home/user/.config/sway/config'
}

get_binding_modes()

Retrieve the list of binding modes that currently configured.

REPLY
An array of strings, with each string being the name of a binding mode. This will always contain at least one mode (currently "default"), which is the default binding mode. (docs)

>>> import swayipc
>>> swayipc.get_binding_modes()
[ 'default', 'resize', 'screenshot', 'dd-term' ]

get_config()

Retrieve the contents of the config that was last loaded.

>>> import swayipc
>>> swayipc.get_config()
'# The entire config contents that was last loaded'

send_tick(payload="")

Issues a TICK event to all clients subscribing to the event to ensure that all events prior to the tick were received. If a payload is given, it will be included in the TICK event. (docs)

>>> import swayipc
>>> swayipc.send_tick()
True

get_binding_state()

Returns the currently active binding mode. (docs)

>>> import swayipc
>>> swayipc.get_binding_state()
'default'

get_inputs()

Retrieve a list of the input devices currently available

REPLY An array of objects corresponding to each input device. (docs)

>>> import swayipc
>>> inputs = swayipc.get_inputs()
>>> inputs[0]
Input(
    identifier='10182:275:GXTP7380:00_27C6:0113_Keyboard', 
    libinput=LibInput(send_events='enabled'), 
    name='GXTP7380:00 27C6:0113 Keyboard',
    product='275', 
    repeat_delay=600.0,
    repeat_rate=25.0,
    type='keyboard', 
    vendor='10182',
    xkb_active_layout_index='0', 
    xkb_active_layout_name='English (US)',
    xkb_layout_names=['English (US)']
)

[!NOTE] The sway-ipc documentation states the following:

The libinput object describes the device configuration for libinput devices. Only properties that are supported for the device will be added to the object. In addition to the possible options listed, all string properties may also be unknown, in the case that a new option is added to libinput.

get_seats()

Retrieve a list of the seats currently configured

REPLY An array of objects corresponding to each seat. (docs)

>>> import swayipc
>>> swayipc.get_seats()
[ 
  Seat(
    capabilities=7,
    devices=[
      Input(...),
      Input(...),
      Input(...),
      ...
    ],
    focus=313,
    name='seat0'
  )

Low-level functions

The following functions are the low-level interface with the IPC socket. These are found in the swayipc.ipc module.

get_socket_location

Obtain the Sway socket location via the I3SOCK environment variable. This is usually unnecessary to call, as calling get_ipc_socket() without any arguments will give you the socket at the default location.

get_ipc_socket

Get a Sway IPC socket as a Python socket.

serialize_message

Take a payload type and payload body, and serialize it into a series of bytes in the expected format.

Arguments

  • payload_type: PayloadType
  • payload: str

deserialize_message

Take a message recieved from the IPC socket, and parse it into a Payload object. This returns a tuple consisting of the message type, the message object (typically a dict or list), and any remainder from the message buffer. The remainder is only needed when using a pattern like subscribe() where multiple messages my be recieved and the buffer needs to be maintained.

Arguments

  • payload: bytes - The raw bytes from the IPC socket.

send_ipc_message

Send a message to the Sway IPC consisting of the given payload_type and message.

Arguments

  • ptype: PayloadType - The PayloadType being sent
  • payload - The serialized payload data being sent

The PayloadType enum

The following enum is present inside of swayipc.ipc.

class PayloadType(enum.Enum):
  RUN_COMMAND = 0
  GET_WORKSPACES = 1
  SUBSCRIBE = 2
  GET_OUTPUTS = 3
  GET_TREE = 4
  GET_MARKS = 5
  GET_BAR_CONFIG = 6
  GET_VERSION = 7
  GET_BINDING_MODES = 8
  GET_CONFIG = 9
  SEND_TICK = 10
  SYNC = 11
  GET_BINDING_STATE = 12
  GET_INPUTS = 100
  GET_SEATS = 101

License

MIT license. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

swayipc-0.1.0.tar.gz (14.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

swayipc-0.1.0-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file swayipc-0.1.0.tar.gz.

File metadata

  • Download URL: swayipc-0.1.0.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.2

File hashes

Hashes for swayipc-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fdf350cc2df4c3ac4da86b3625feebd5b7fa3a959ceadc2b6975af19e49a8372
MD5 b6603b94e241def2f30e085f57030d23
BLAKE2b-256 277720cd5f1e6d2898482df1f355ea3ba28629f1fb18ba20e2c8fcf2ffce352c

See more details on using hashes here.

File details

Details for the file swayipc-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: swayipc-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.2

File hashes

Hashes for swayipc-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a3ca5ff0f7f79e399a99e4c780e786eb78561e7290e79aaa47b34f54f7356278
MD5 31eefcbc13199a5335f8915bf640eb27
BLAKE2b-256 0cdc542b26eec11db74cf3f8207bec6c66122fe0c95271ba69262fe055785752

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page