Skip to content

Commit

Permalink
Graphics protocol: Support for positioning images relative to other i…
Browse files Browse the repository at this point in the history
…mages

Fixes #6617
  • Loading branch information
kovidgoyal committed Oct 27, 2023
1 parent aee14a4 commit 52d5a46
Show file tree
Hide file tree
Showing 8 changed files with 398 additions and 43 deletions.
2 changes: 2 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ Detailed list of changes

- A new :doc:`escape code <pointer-shapes>` that can be used by programs running in the terminal to change the shape of the mouse pointer (:iss:`6711`)

- Graphics protocol: Support for positioning :ref:`images relative to other images <relative_image_placement>` (:iss:`6400`)

- A new option :opt:`single_window_padding_width` to use a different padding when only a single window is visible (:iss:`6734`)

- A new mouse action ``mouse_selection word_and_line_from_point`` to select the current word under the mouse cursor and extend to end of line (:pull:`6663`)
Expand Down
56 changes: 56 additions & 0 deletions docs/graphics-protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,58 @@ placements from the protocol perspective. They cannot be manipulated using
graphics commands, instead they should be moved, deleted, or modified by
manipulating the underlying Unicode placeholder as normal text.

.. _relative_image_placement:

Relative placements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 0.31.0
Support for positioning images relative to other images

You can specify that a placement is positioned relative to another placement.
This is particularly useful in combination with
:ref:`graphics_unicode_placeholders` above. It can be used to specify a single
transparent pixel image using a Unicode placeholder, which moves around
naturally with the text, the real image(s) can base their position relative to
the placeholder.

To specify that a placement should be relative to another, use the
``P=<image_id>,Q=<placement_id>`` keys, when creating the relative placement.
For example::

<ESC>_Ga=p,i=<image_id>,p=<placement_id>,P=<parent_img_id>,Q=<parent_placement_id><ESC>\

This will create a *relative placement* that refers to the *parent placement* specified
by the ``P`` and ``Q`` keys. When the parent placement moves, the relative
placement moves along with it. The relative placement can be offset from the
parent's location by a specified number of cells, using the ``H`` and ``V``
keys for horizontal and vertical displacement. Positive values move right and
down. Negative values move left and up.

The lifetime of a relative placement is tied to the lifetime of its parent. If
its parent is deleted, it is deleted as well. If the image that the relative
placement is a placement of, has no more placements, the image is deleted as
well. Thus, a parent and its relative placements form a *group* that is managed
together.

A relative placement can refer to another relative placement as its parent.
Thus the relative placements can form a chain. It is implementation dependent
how long a chain of such placements is allowed, but implementation must allow
a chain of length at least 8. If the implementation max depth is exceeded, the
terminal must respond with the ``ETOODEEP`` error code.

Virtual placements created for Unicode placeholder based images cannot also be
relative placements. However, a relative placement can refer to a virtual
placement as its parent. If a client attempts to make a virtual placement
relative the terminal must respond with the ``EINVAL`` error code.

Terminals are required to reject the creation of a relative placement
that would create a cycle, such as when A is relative to B and B is relative to
C and C is relative to A. In such cases, the terminal must respond with the
``ECYCLE`` error code.

If a client attempts to create a reference to a placement that does not exist
the terminal must respond with the ``ENOPARENT`` error code.

Deleting images
---------------------
Expand Down Expand Up @@ -962,6 +1014,10 @@ Key Value Default Description
``U`` Positive integer ``0`` Set to ``1`` to create a virtual placement for a Unicode placeholder.
``1`` is to not move the cursor at all when placing the image.
``z`` 32-bit integer ``0`` The *z-index* vertical stacking order of the image
``P`` Positive integer ``0`` The id of a parent image for relative placement
``Q`` Positive integer ``0`` The id of a placement in the parent image for relative placement
``H`` 32-bit integer ``0`` The offset in cells in the horizontal direction for relative placement
``V`` 32-bit integer ``0`` The offset in cells in the vertical direction for relative placement

**Keys for animation frame loading**
-----------------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions gen/apc_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ def graphics_parser() -> None:
'z': ('z_index', 'int'),
'C': ('cursor_movement', 'uint'),
'U': ('unicode_placement', 'uint'),
'P': ('parent_id', 'uint'),
'Q': ('parent_placement_id', 'uint'),
'H': ('offset_from_parent_x', 'int'),
'V': ('offset_from_parent_y', 'int'),
}
text = generate('parse_graphics_code', 'screen_handle_graphics_command', 'graphics_command', keymap, 'GraphicsCommand')
write_header(text, 'kitty/parse-graphics-command.h')
Expand Down
Loading

0 comments on commit 52d5a46

Please sign in to comment.