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.1.tar.gz (14.1 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.1-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: swayipc-0.1.1.tar.gz
  • Upload date:
  • Size: 14.1 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.1.tar.gz
Algorithm Hash digest
SHA256 e34a83ca47ee0db92afb8c951fecaede3832743af48f2128b0e955dc0ce617c9
MD5 a1835fbcd213c31fecb8b50730288e3d
BLAKE2b-256 538a6944e844597837c90444b489f76a2c29e24d1136805e1632fd55659fec42

See more details on using hashes here.

File details

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

File metadata

  • Download URL: swayipc-0.1.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4f5d038357589e35292444687fb202fda74ec5673ec631a659636242d4e9c1da
MD5 27037603454979c607cf545bdd241073
BLAKE2b-256 2480ab2cc33e00ccc4218525a33db6006bc64b8afc06a4615b9d53fb2e151f2f

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