Ensure initial PTY size matches Terminal (if any)

If a PTY has a terminal_path set to a valid Terminal, then ensure that
the initial cols and rows of PTY match the cols and rows of the Terminal
when calling fork() or open(), otherwise PTY will output wrong-sized
data for the Terminal until resized.

Fixes #56.
This commit is contained in:
Leroy Hopson 2022-08-12 10:24:54 +12:00
parent 00a34a9177
commit 054c7c9ad4
No known key found for this signature in database
GPG key ID: D2747312A6DB51AA
4 changed files with 231 additions and 34 deletions

View file

@ -167,6 +167,61 @@ class Helper:
return {rows = int(size.x), cols = int(size.y)}
class TestPTYSize:
extends "res://addons/gut/test.gd"
# Tests to check that psuedoterminal size (as reported by the stty command)
# matches the size of the Terminal node. Uses various scene tree layouts with
# Terminal and PTY nodes in different places.
# See: https://github.com/lihop/godot-xterm/issues/56
const PTY := preload("res://addons/godot_xterm/pty.gd")
const Terminal := preload("res://addons/godot_xterm/terminal.gd")
var pty: PTY
var terminal: Terminal
var scene: Node
var regex := RegEx.new()
func before_all():
regex.compile(".*rows (?<rows>[0-9]+).*columns (?<columns>[0-9]+).*")
func before_each():
scene = add_child_autofree(preload("res://test/scenes/pty_and_terminal.tscn").instance())
func test_correct_stty_reports_correct_size():
for s in [
"PTYChild",
"PTYSiblingAbove",
"PTYSiblingBelow",
"PTYCousinAbove",
"PTYCousinBelow",
"PTYCousinAbove2",
"PTYCousinBelow2"
]:
pty = scene.get_node(s).find_node("PTY")
terminal = scene.get_node(s).find_node("Terminal")
pty.call_deferred("fork", OS.get_environment("SHELL"))
pty.call_deferred("write", "stty -a | head -n1\n")
var output := ""
while not "rows" in output and not "columns" in output:
output = (yield(pty, "data_received")).get_string_from_utf8()
var regex_match = regex.search(output)
var stty_rows = int(regex_match.get_string("rows"))
var stty_cols = int(regex_match.get_string("columns"))
assert_eq(
stty_rows,
terminal.rows,
"Expected stty to report correct number of rows for layout '%s'" % s
)
assert_eq(
stty_cols,
terminal.cols,
"Expected stty to report correct number of columns for layout '%s'" % s
)
class LinuxHelper:
extends Helper

View file

@ -0,0 +1,131 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/godot_xterm/terminal.gd" type="Script" id=1]
[ext_resource path="res://addons/godot_xterm/pty.gd" type="Script" id=2]
[node name="PTYandTerminal" type="Node"]
[node name="PTYChild" type="Node" parent="."]
[node name="Terminal" type="Control" parent="PTYChild"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
[node name="PTY" type="Node" parent="PTYChild/Terminal"]
script = ExtResource( 2 )
terminal_path = NodePath("..")
env = {
"COLORTERM": "truecolor",
"TERM": "xterm-256color"
}
[node name="PTYSiblingAbove" type="Node" parent="."]
[node name="PTY" type="Node" parent="PTYSiblingAbove"]
script = ExtResource( 2 )
terminal_path = NodePath("../Terminal")
env = {
"COLORTERM": "truecolor",
"TERM": "xterm-256color"
}
[node name="Terminal" type="Control" parent="PTYSiblingAbove"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
[node name="PTYSiblingBelow" type="Node" parent="."]
[node name="Terminal" type="Control" parent="PTYSiblingBelow"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
[node name="PTY" type="Node" parent="PTYSiblingBelow"]
script = ExtResource( 2 )
terminal_path = NodePath("../Terminal")
env = {
"COLORTERM": "truecolor",
"TERM": "xterm-256color"
}
[node name="PTYCousinAbove" type="Node" parent="."]
[node name="Node" type="Node" parent="PTYCousinAbove"]
[node name="PTY" type="Node" parent="PTYCousinAbove/Node"]
script = ExtResource( 2 )
terminal_path = NodePath("../../Terminal")
env = {
"COLORTERM": "truecolor",
"TERM": "xterm-256color"
}
[node name="Terminal" type="Control" parent="PTYCousinAbove"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
[node name="PTYCousinBelow" type="Node" parent="."]
[node name="Terminal" type="Control" parent="PTYCousinBelow"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
[node name="Node" type="Node" parent="PTYCousinBelow"]
[node name="PTY" type="Node" parent="PTYCousinBelow/Node"]
script = ExtResource( 2 )
terminal_path = NodePath("../../Terminal")
env = {
"COLORTERM": "truecolor",
"TERM": "xterm-256color"
}
[node name="PTYCousinAbove2" type="Node" parent="."]
[node name="Node" type="Node" parent="PTYCousinAbove2"]
[node name="Node" type="Node" parent="PTYCousinAbove2/Node"]
[node name="PTY" type="Node" parent="PTYCousinAbove2/Node/Node"]
script = ExtResource( 2 )
terminal_path = NodePath("../../../Control/Terminal")
env = {
"COLORTERM": "truecolor",
"TERM": "xterm-256color"
}
[node name="Control" type="Control" parent="PTYCousinAbove2"]
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Terminal" type="Control" parent="PTYCousinAbove2/Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
[node name="PTYCousinBelow2" type="Node" parent="."]
[node name="Control" type="Control" parent="PTYCousinBelow2"]
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Terminal" type="Control" parent="PTYCousinBelow2/Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
[node name="Node" type="Node" parent="PTYCousinBelow2"]
[node name="Node" type="Node" parent="PTYCousinBelow2/Node"]
[node name="PTY" type="Node" parent="PTYCousinBelow2/Node/Node"]
script = ExtResource( 2 )
terminal_path = NodePath("../../../Control/Terminal")
env = {
"COLORTERM": "truecolor",
"TERM": "xterm-256color"
}