Implement terminal resize capture ("r" event)

This commit is contained in:
Marcin Kulik
2023-08-14 16:38:10 +02:00
parent ff14e5b5be
commit a9dc2e5396
5 changed files with 34 additions and 7 deletions

View File

@@ -1,7 +1,7 @@
import os
import sys
from os import path
from typing import Any, Callable, Optional
from typing import Any, Callable, Optional, Tuple
from ..file_writer import file_writer
@@ -44,13 +44,16 @@ class writer(file_writer):
def write_stdout(self, _ts: float, data: Any) -> None:
self._write(data)
# pylint: disable=no-self-use
def write_stdin(self, ts: float, data: Any) -> None:
pass
def write_marker(self, ts: float) -> None:
pass
def write_resize(self, ts: float, size: Tuple[int, int]) -> None:
cols, rows = size
self._write(f"\x1b[8;{rows};{cols}t".encode("utf-8"))
# pylint: disable=consider-using-with
def _open_file(self) -> None:
if self.path == "-":

View File

@@ -12,6 +12,7 @@ from typing import (
List,
Optional,
TextIO,
Tuple,
Union,
)
@@ -148,6 +149,10 @@ class writer(file_writer):
def write_marker(self, ts: float) -> None:
self.__write_event(ts, "m", "")
def write_resize(self, ts: float, size: Tuple[int, int]) -> None:
cols, rows = size
self.__write_event(ts, "r", f"{cols}x{rows}")
# pylint: disable=consider-using-with
def _open_file(self) -> None:
if self.path == "-":

View File

@@ -41,8 +41,14 @@ def record(
add_marker_key = key_bindings.get("add_marker")
input_data = bytes()
def set_pty_size() -> None:
cols, rows = get_tty_size()
def handle_resize() -> None:
size = get_tty_size()
set_pty_size(size)
assert start_time is not None
writer.write_resize(time.perf_counter() - start_time, size)
def set_pty_size(size: Tuple[int, int]) -> None:
cols, rows = size
buf = array.array("h", [rows, cols, 0, 0])
fcntl.ioctl(pty_fd, termios.TIOCSWINSZ, buf)
@@ -149,7 +155,7 @@ def record(
if sig in EXIT_SIGNALS:
crfds.remove(signal_fd)
if sig == signal.SIGWINCH:
set_pty_size()
handle_resize()
if pty_fd in wfds:
n = os.write(pty_fd, input_data)
@@ -164,7 +170,7 @@ def record(
fcntl.fcntl(pty_fd, fcntl.F_SETFL, flags)
start_time = time.perf_counter()
set_pty_size()
set_pty_size(get_tty_size())
with SignalFD(EXIT_SIGNALS + [signal.SIGWINCH]) as sig_fd:
with raw(tty_stdin_fd):

View File

@@ -134,6 +134,9 @@ class async_writer(async_worker):
def write_marker(self, ts: float) -> None:
self.enqueue([ts, "m", None])
def write_resize(self, ts: float, size: Tuple[int, int]) -> None:
self.enqueue([ts, "r", size])
def run(self) -> None:
try:
with self.writer as w:
@@ -148,6 +151,8 @@ class async_writer(async_worker):
w.write_stdin(self.time_offset + ts, data)
elif etype == "m":
w.write_marker(self.time_offset + ts)
elif etype == "r":
w.write_resize(self.time_offset + ts, data)
except IOError:
for event in iter(self.queue.get, None):
pass

View File

@@ -15,6 +15,7 @@ Example file:
[1.001376, "o", "That was ok\rThis is better."]
[1.500000, "m", ""]
[2.143733, "o", "Now... "]
[4.050000, "r", "80x24"]
[6.541828, "o", "Bye!"]
```
@@ -115,7 +116,7 @@ Where:
* `time` (float) - indicates when this event happened, represented as the number
of seconds since the beginning of the recording session,
* `event-type` (string) - one of: `"o"`, `"i"`, `"m"`
* `event-type` (string) - one of: `"o"`, `"i"`, `"m"`, `"r"`
* `event-data` (any) - event specific data, described separately for each event
type.
@@ -176,6 +177,13 @@ the user to resume.
`event-data` can be used to annotate a marker. Annotations may be used to e.g.
show a list of named "chapters".
#### "r" - resize
Event of type `"r"` represents terminal resize.
`event-data` contains new terminal size (columns + rows) formatted as
`"{COLS}x{ROWS}"`, e.g. `"80x24"`.
## Notes on compatibility
Version 2 of asciicast file format solves several problems which couldn't be